Hiding views declaratively based on screen size in Android - 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

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.

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, ...)

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.

Have you looked at using includes and multiple layouts organized into the appropriate size/orientation layout folders? Some layouts could either simply not have the button or have it hidden by default.
Re-using Layouts with include
Providing Alternative Resources

Related

When to use attrs.xml, when dimens.xml?

I like to integrate ads with AppLovin into my Android App.
In their documentation they say:
Declare the base banner height of 50dp in res/values/attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="banner_height">50dp</dimen>
</resources>
I also have a dimens.xml present with other <dimen... value's for my app. They work from there as well.
What is the difference between attrs.xml and dimens.xml? What to use in a situation like this?
attrs.xml is a file that allows you to define custom attributes for your views in XML layout files. These attributes can be used to customize the appearance and behavior of your views, and can be accessed programmatically in your Java code.
dimens.xml on the other hand, is a file that allows you to define dimension values for use in your app. These values can be used to set the size and layout of views in your XML layout files, and can also be accessed programmatically in your Java code.
In this situation, you should use dimens.xml to define the banner_height dimension, because you will use this value to set the height of the banner ad view in your layout.
You could also use attrs.xml to define the banner_height attribute, but since you are defining a dimension value, not an attribute, it would be better to use dimens.xml instead.
It doesn't actually matter - <attr> and <dimen> are both value resources, and you can put them in any file in the res/values folder. They'll all be combined into the same set of resources, so the actual file you use is up to you! So you can do this if you want:
# res/values/whatever.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="someDimension">48dp</dimen>
<attr name="someColour" format="color"></attr>
</resources>
and it'll work exactly the same as if you used attrs.xml and dimens.xml. It's just convention to put attrs and declare-styleable things in a file called attrs.xml, all your dimension resources in dimens.xml, all your strings in strings.xml...
But you don't have to do that, it's up to you! For example, you might want certain resource strings to be stored in a different file, for organisation (maybe they shouldn't be translated). Or maybe some values are common to all configs and you want those in a single file, and you want a separate file for the qualified stuff (that goes in folders based on API level, night theme etc)

Android is ignoring /res/values-large/strings.xml

I want to use a different string resource on small screens but Android always uses the default string. Am I doing it wrong?
/res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="continue">Continue</string>
</resources>
/res/values-large/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="continue">Continue to Next Page</string>
</resources>
#string/continue always resolves to "Continue", even on large screens. It does, however use the dimensions in /res/values-large/dimens.xml so I'm sure I'm using the right resource qualifier. I also tried /res/values-w550dp/strings.xml and it didn't work either.
Am I doing something wrong or is this a limitation of Android?
values-large is only available for dimens and styles, but not for string resources.
one could possibly add custom string-arrays and then look them up accordingly.
see Android Resource Types.

Error by including drawable xml-file

Hello community,
I want to iclude different drawable xml-files into my activity_main.xml
However,when I want to includ following code :
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<size
android:layout_height="110dp" />
</shape>
</item>
</selector>
the name is button_height.xml into my main-file:
<Button
android:id="#+id/cmda1"
android:layout_width="110dp"
android:layout_height="#drawable/button_height" />
It does not work and Eclipse says only:
You must supply a layout_height attribute.
and
error in an XML file: aborting build.
I searched an answer in the internet but dont found one.
But I think its an easy mistake lots of people are doing.
so, I hope for usefull answers
and sorry for my awful english.
Your whole idea of drawable, selector and dimension is messed up. Can't put height in selector and also selectors (which are drawable) as height.
Do this.
If you want to use xml to get height
Add a file in res folder with name res/values/dimens.xml and add this line in that
<resources>
<integer name="btn_cmda_height" >110dp</integer>
</resources>
and change the button cmda1 height property as
android:layout_height="#dimen/btn_cmda_height"
Make it dynamic for various screen sizes by creating these files which will hold different values. Although this is the old way.
Read more about new way to do this here
res/values/dimens.xml
res/values-small/dimens.xml
res/values-normal/dimens.xml
res/values-xlarge/dimens.xml
If you don't want to use xml to get height
just do this android:layout_height="110dp" in the button cmda1 height property
NOTE:
Your selector code is wrong and not required at all. Selectors are used to define the background state of a view

TextView textSize and #string in Android

I have the following xml code:
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Press Button" <!--Warning -->
android:textSize="45dp" <!--Warning -->
android:layout_gravity="center"
android:gravity="center"
android:id="#+id/tvDisplay" />
In the xml code i found two warning first that dp contains that which i got the waring to use sp indeed. What is the reason it showing so?
Second warning and may be error is that i am using android:text="Press Button" it tell me to use #string indeed. If i uses the same #string is displayed in text which look awkward. What is the reason for it!
Hardcoded String value in View is not recommeded by developer.android.com as making of Android Application compatible with different languages is twisted up to.
Referenced from
To add support for more languages, create additional values directories inside res/ that include a hyphen and the ISO country code at the end of the directory name. For example, values-es/ is the directory containing simple resourcess for the Locales with the language code "es". Android loads the appropriate resources according to the locale settings of the device at run time.
Once you’ve decided on the languages you will support, create the resource subdirectories and string resource files. For example:
MyProject/
res/
values/
strings.xml
values-es/
strings.xml
values-fr/
strings.xml
Add the string values for each locale into the appropriate file.
At runtime, the Android system uses the appropriate set of string resources based on the locale currently set for the user's device.
For example, the following are some different string resource files for different languages.
English (default locale), /values/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="title">My Application</string>
<string name="hello_world">Hello World!</string>
</resources>
Spanish, /values-es/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="title">Mi Aplicación</string>
<string name="hello_world">Hola Mundo!</string>
</resources>
Referring to your OP:
XML file saved at res/values/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="press">Press Button</string>
</resources>
This layout XML applies a string to a View:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/press"
android:textSize="45dp" <!--Warning -->
android:layout_gravity="center"
android:gravity="center"
android:id="#+id/tvDisplay" />
This application code retrieves a string:
String string = getString(R.string.hello);
Use sp for setting size as suggested by developer.android.com
sp : Scale-independent Pixels - This is like the dp unit, but it is also scaled by the user's font size preference. It is recommend you use this unit when specifying font sizes, so they will be adjusted for both the screen density and the user's preference.
XML file saved at res/values/dimens.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="font_size">16sp</dimen>
</resources>
This application code retrieves a dimension
Resources res = getResources();
float fontSize = res.getDimension(R.dimen.font_size);
This layout XML applies dimensions to attributes:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Press Button" <!--Warning -->
android:textSize="#dimen/font_size"
android:layout_gravity="center"
android:gravity="center"
android:id="#+id/tvDisplay"
/>
Recommended dimension type for text is "sp" for scaled-pixels (example: 15sp)
from the developer.android
Android stander TextView size is use SP and you are hardcode String that i give warning.
Please User your String.xml in value folder and select this String then it do not give any error.
Thanks
It's better to use SP instead of DP.
It's recommend to use always string resources file, because if you need to change a single #String used in multiples xml files, you have to change only one time. Vice-versa, if you write your strings inside the xml layout files, if you need to change a string you need to search for the string, search for the xml file and then change as many occurrances you need.
In conclusion, it is not a good practice to hard code strings. You should specifies them to a string resource file and then reference them in your layout.This allows you to update every occurrence of a single word in all layouts at the same time by just editing your strings.xml file.
It is also necessary for supporting multiple languages definitions as a separate strings.xml One file for one language!

Different screensize and language in android

I want to support different screen sizes and languages at the same time. So I got some folders for my layout like
layout (German)
layout-en (English)
layout-fr (French)
etc...
and I got layout-large for big screens. So when I open another language in the large screen I got the layout from the small screen. Is there a way to manage this? layout-large-fr or layout-fr-large did not work...
And of course I defined translated strings.
Try this one:
Create on layout file for each language. Create on layout.xml in res/values-xx with this content:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="main_layout" type="layout">#layout/activity_main_xx</item>
</resources>
The result should looks like this:

Categories

Resources