Controlling view visibility from a resources
Solution 1
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.
Solution 2
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.
user1139880
Updated on June 09, 2022Comments
-
user1139880 almost 2 years
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).
-
user1139880 about 12 yearsThanks Calvin. I was trying to avoid duplicating the layout, unless I can generate them automatically from a template at build time. Don't know if eclipse supports it and how standard it will be.
-
user1139880 about 12 yearsThanks Keyhan, I will give it a try and report here. Will this approach also help with this question? stackoverflow.com/questions/9745227/… . I have 5 different sizes times two modes (portrait and langscape). Use the style also to control the ImageView size? This way I will have a single layout with two images and 5 pairs of orientation/portrait styles. (working around the limitations of RemoteViews is not fun ;-)).
-
user1139880 about 12 yearsWorks well. This was a great help!. Thanks Keyhan.
-
denispyr almost 11 yearsThe suggested solution involves the usage of Style Resources
-
TalkLittle over 10 yearsIt also works declaring them as
<integer>
rather than<string>
-
Bartek Lipinski over 9 yearsthe good practice would be to keep the original android values for visible, invisible and gone (not 0, 1, 2, but 0, 4, 8)
-
Flávio Faria over 9 yearsWell, that's not exaclty how it works. If you check the
View
class code, these values (0, 1 and 2) are used to access the positions of this member:private static final int[] VISIBILITY_FLAGS = {VISIBLE, INVISIBLE, GONE};
. That's why you can't use 0, 4 and 8, because 0, 1 and 2 stand for VISIBLE, INVISIBLE and GONE indices. -
TWiStErRob about 9 yearsCreating a whole style just to set an attribute is not a good practice, especially if you need to set more attributes in styles already (you can't have two styles on a view). Flávio's answer is much cleaner.
-
charles-allen over 6 yearsAliases doesn't work for me (i.e.
view_visible
). It only works if I assign 0, 1, 2 to an integer resource that I use directly. (but +1 for that bit!!) -
NickUnuchek almost 5 yearsFrom
android.view.View#VISIBLE``android.view.View#INVISIBLE
andandroid.view.View#GONE
values of variables should be<enum name="visible" value="0" /> <enum name="invisible" value="4" /> <enum name="gone" value="8" />