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).
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With