Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hiding views declaratively based on screen size in Android

In android xml:ish

Is there any way to change a visibility attribute based on the layout size/orientation in the xml directly?

I have a button in a fragment that should be visible for small screens sizes only. On larger sizes, let's say layout-large, I want it to be hidden.

Sure, I can write code for this without any problem but for academic reasons I would like to know it it's possible to do something like this.

<Button
     android:id="@+id/btn_check_availability"
     style="@style/product_info_footer_button"
     android:layout_width="fill_parent"
     android:layout_height="35dp"
     android:text="@string/check_availability"
     android:visibility="<magic expression here>" />

Thanks

// Johan

like image 612
Johan Karlsson Avatar asked Jun 12 '14 15:06

Johan Karlsson


3 Answers

This answer is based off the explanation provided here by Flávio Faria.

The visible, gone, etc can be values mapped to their corresponding enum values in a string resource - which means you can create a visibilty.xml with string resources for each layout you want, and Android will automatically resolve the one you want for each screen type.

I'd recommend the following:

/res/values/visibilty.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- Enum values pulled from Android source -->
    <string name="visibility_visible">0</string>
    <string name="visibility_invisible">1</string>
    <string name="visibility_gone">2</string>

    <string name="product_info_footer_button_visibility">@string/visibility_visible</string>
</resources>

/res/values-large/visibilty.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="product_info_footer_button_visibility">@string/visibility_invisible</string>
</resources>

And then you can reference the visibility as follows for your button:

<Button
     android:id="@+id/btn_check_availability"
     style="@style/product_info_footer_button"
     android:layout_width="fill_parent"
     android:layout_height="35dp"
     android:text="@string/check_availability"
     android:visibility="@string/product_info_footer_button_visibility" />

Warning: This depends on the device having the same enum values for visibility (0/1/2) as defined in the AOSP source. Device manufacturers and custom ROM creators can change these values, in which case this code will likely not work as desired.

like image 85
Adam S Avatar answered Sep 19 '22 16:09

Adam S


The android:visibility attribute is an int (like many attributes) so you can do the following :

Define a resource file named visibility.xml in values-port and values-land resource directories. The content of this file is like this :

values-port/visibility.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="buttonvisibility">0</integer> <!-- 0 is the value for android:visible -->
</resources>

values-land/visibility.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="buttonvisibility">1</integer> <!-- 1 is the value for android:invisible -->
</resources>

and in your layout.xml :

<Button
 android:id="@+id/btn_check_availability"
 style="@style/product_info_footer_button"
 android:layout_width="fill_parent"
 android:layout_height="35dp"
 android:text="@string/check_availability"
 android:visibility="@integer/buttonvisibility" />

It works : btn_check_availability is visible in portrait and invisible in landscape.

Note : this example use layout orientation as discriminator, but you can of course do it with any resource qualifier (like dimension, density, ...)

like image 38
ben75 Avatar answered Sep 22 '22 16:09

ben75


There is no magic expressions available in XML. If only.

There are two approaches to this problem:

a/ use the drawable folder system. Drawable folders can be copied and named to be DPI aware following the conventions dictated here: Supporting Multiple Screens.

b/ Do it programmatically. On runtime check for screen DPI and show/hide view accordingly.

like image 31
MLProgrammer-CiM Avatar answered Sep 22 '22 16:09

MLProgrammer-CiM