Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Controlling view visibility from a resources

I have a layout that contains two ImageViews. I want one of them to be visible in portrait and the other in landscape. How do I achieve it using resources? (I know how to set it programmatically for but this specific use I need to achieve it using resources).

I tried something like

in res/layout/may_layout.xml:

...
<ImageView
      android:id="@+id/image1"
      android:visibility="@integer/visible_in_portrait"   <<-- is this allowed?
      ...
/>
<ImageView
      android:id="@+id/image2"
      android:visibility="@integer/visible_in_landscape"   
      ...
/>

in res/values/integers.xml:

...
<!-- NOTE: 0 and 8 are VISIBLE and GONE respectively -->
<integer name="visibile_in_portrait">0</integer>
<integer name="visibile_in_landscape">8</integer>

in res/values-land/integers.xml:

...
<integer name="visibile_in_portrait">8</integer>
<integer name="visibile_in_landscape">0</integer>

But I get a runtime error (index out of bound) when trying to inflate the images. When I remove the android:visibility statements, the program runs but I see both images.

Q: What is the way to use a resource as a value for the android:visibility attribute?

(if you wonder why setting it programmatically will not help me, it has to do with automatic landspace/portrait switch of app widgets with file uri bitmaps).

like image 319
user1139880 Avatar asked Mar 17 '12 16:03

user1139880


2 Answers

This is an old question that has already been accepted, but the following solution may help someone else:

If you check res/values/attrs.xml in Android source code, you'll see the definition of visibility property like this:

 <!-- Controls the initial visibility of the view.  -->
    <attr name="visibility">
        <!-- Visible on screen; the default value. -->
        <enum name="visible" value="0" />
        <!-- Not displayed, but taken into account during layout (space is left for it). -->
        <enum name="invisible" value="1" />
        <!-- Completely hidden, as if the view had not been added. -->
        <enum name="gone" value="2" />
    </attr>

This attribute expects a string value (visible, invisible, gone) that will be converted to (0, 1, 2) respectively. So, you can declare integer resources containing these values like this:

values/integers.xml

<integer name="visible_in_portrait">2</integer> <!-- This is GONE -->

values-land/integers.xml

<integer name="visible_in_landscape">0</integer> <!-- This is VISIBLE -->

However, if you want to make it even better in order to stop guessing these numeric constants every time, you could do like this:

values/integers.xml

<!-- These are alias for the constants we'll reference below -->
<integer name="view_visible">0</integer> <!-- This is VISIBLE -->
<integer name="view_invisible">1</integer> <!-- This is INVISIBLE -->
<integer name="view_gone">2</integer> <!-- This is GONE -->

<integer name="visible_in_portrait">@integer/view_gone</integer> <!-- We're referencing the visibility alias we declared above -->

values-land/integers.xml

<integer name="visible_in_landscape">@integer/view_visible</integer>

You can use this approach or the one suggested by Keyhan. Choose the one that fits you better.

like image 66
Flávio Faria Avatar answered Nov 08 '22 05:11

Flávio Faria


it will be possible when you use this trick, add your visibility line to a style and put two instances of that file in -land and normal mode.

I mean in file styles.xml in folder values put a style with name s1, and put android:visibility=visible in that, and in styles.xml in folder values-land put a style with name s1, and put android:visibility=gone.

also, in file styles.xml in folder values put a style with name s2, and put android:visibility=gone in that, and in styles.xml in folder values-land put a style with name s2, and put android:visibility=visible.

and then, set s1 to first imageview and s2 to second.

solution given by dear Calvin is also correct, but when you have a complex layout that may change during time, having one layout file would be better, and will have less need to change.

like image 36
Keyhan Asghari Avatar answered Nov 08 '22 04:11

Keyhan Asghari