android layout load different image resources at orientation change - android

I would like to have a solution in xml or a keyword for what to search to solve my problem:
I have multiple screens. Each screen has his own xml in layout folder. For eg a part of the code :
<RelativeLayout
android:id="#+id/headerLayout"
android:layout_width="fill_parent"
android:layout_height="80dp"
android:background="#drawable/header" >
<Button
android:id="#+id/btBack"
android:layout_width="55dp"
android:layout_height="33dp"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dip"
android:layout_marginTop="10dip"
android:background="#drawable/bt_back"
/>
</RelativeLayout>
now, I would like to change the "#drawable/header" value runtime when is a rotation, prefferable to configure and Android change not me in Java code. The same thing is done with
"#drawable/bt_back", which is a bt_back.xml file at drawable folder and has a selector. His content is here:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- selected state -->
<item android:drawable="#drawable/bt_back_pressed" android:state_pressed="true" android:state_selected="false"/>
<item android:drawable="#drawable/bt_back_pressed" android:state_pressed="false" android:state_selected="true"/>
<item android:drawable="#drawable/bt_back_pressed" android:state_pressed="true" android:state_selected="true"/>
<!-- unselected state (default) -->
<item android:drawable="#drawable/bt_back_normal"/>
</selector>
Now in folder what I want drawable-hdpi, drawable-ldpi, I just need to put those 2 files and the android system is auto-handling the image changes for pressed and normal state depending on user device dpi.
The same thing I would like to have for header for rotation from portrait and landscape. Eg it should alternate the header_port.png to header-land.png.
How is possible? Any ideas?
I don't wand different .xml layout for landscape, nor digg in java code.
Maybe in different folder the resources for header, described here ? port and land?

You are able to create a drawable-land-hdpi directory. Put your landscape versions in the qualified folders and android should automatically load them for you.

To elaborate on #toadzky's answer, you can create a different drawable directory for any qualifier that you find on this Android Developer page, and put images with the same name in each, and android will automatically know which one to use. The same is true for layouts in the layout (or layout-land, etc.) folder, value xml files (e.g., string resources--useful for localization--or themes), in the values folders, or any other things you normally find in the res folder.
It's also important to note that the way its precedence works (with respect to which directory it picks for resources) is, if I recall correctly, "first match after excluding all incompatible directories".
So, if you had only drawable-hdpi and drawable, and you had an mdpi device, it would eliminate all directories qualified with hdpi, and select from the remaining directories (so you'd end up with the version from the drawable folder). Further explanation is found on the linked page, under "How Android Finds the Best-matching Resource".

Related

How to give icon path to xml in android

I've created a directory inside drawable directory which contains two icons "empty_star.png". Now how to give address of these icons in style.xml
i tried following:
<item android:state_selected="true"
android:state_window_focused="true"
android:drawable="drawable/icons/empty_star" />
<item android:drawable="drawable/icons/empty_star" />
but it shows error.
i also tried #drwable/icons/empty_star but still getting error.
Try this:
android:drawable="#drawable/empty_star"
The resources mechanism doesn't support subfolders in the drawable directory. You need to keep that hierarchy flat. Place your images in drawable folder and use it as android:drawable="#drawable/empty_star"
Can the Android drawable directory contain subdirectories?
According to the answer posted earlier, resource mechanism does not support sub folders in drawable folder. So you should maintain flat hierarchy.

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
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

Graphical layout won't show my button background

I have a button background described as follows in its own "custom_easy_but.xml" in a directory res/drawable as follows:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#drawable/but_easy_p"
android:state_pressed="true"/>
<item android:drawable="#drawable/but_easy" />
</selector>
Then I have a layout called modeselect.xml which includes the following code:
<Button
android:id="#+id/easy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:background="#drawable/custom_easy_but"
android:text="#string/Easy" />
then I have a set different sized images in files called but_easy.png and but_easy_p.png in separate directories res/drawable-large and res/drawable-normal. The code compiles, runs and displays exactly the right button background images on a variety of phones... but if I look at the file modeselect.xml using eclipse and switch to the "graphical layout" view, I do not see the background images at all, and underneath the graphical view I see
failed to parse file c:\blah\blah\res\drawable\custom_easy_but.xml
and
couldn't resolve resource #drawable/but_easy_p
How can it be that the real phones can sort out all the xml but eclipse can't?
Be sure you have set the correct Screen size in the graphical Editor. If You had chosen a screen size, where You got no resources, Your layout will not be shown.

rollover android

I want to make a rollover with android.
I saw that it is necesarry to write a XML like :
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/verde" />
<item android:drawable="#drawable/rojo" />
</selector>
I saved it with the name button.xml.
I don't know in which folder save it.
Then I tried to used the reference in my layout.xml
I change the background attribute for my button in my layout.xml from
android:background="#drawable/red"
and use the
android:background="#drawable/button"
Save button.xml in the folder res/drawable if it's applicable for all screen sizes/devices, otherwise put it in the folder with the appropriate qualifier suffix (e.g. drawable-hdpi, drawable-ldpi etc).
See here (http://developer.android.com) for a full example, and explanation of other states you could include.

Whats the best way to build for multiple screen sizes?

I'm building an app now and I want it to work well across multiple screen sizes (phones, 7inch tablets and 10inch tablets). I've looked at the document on Supporting Multiple Screens but i still have some questions.
Right now I have 5 different layout folders, layout-: normal, large, xlarge, sw600dp and sw720dp. Is this the best way to build for all screen sizes?
And when i try to optimize each layout say the normal size which covers some 3 and 4 inch screens I get issues where I can't get my layout to look right on all of them.
What am I doing right and what could I change?
I don't believe that there's any best way, it will be just your way to do it. If you are planing to make the Images, buttons, textview smaller or bigger you can use the method you use or style.xml.
Style.xml example:
You will have some folders like:
values
values-large
values-normal
values-small
values-xlarge
where inside the folders you have a styles.xml with different values:
<style name="BigTextStyle">
<item name="android:textSize">60dp</item>
</style>
<style name="SmallTextStyle">
<item name="android:textSize">48dp</item>
</style>
<style name="ImageSize">
<item name="android:layout_width">100dp</item>
<item name="android:layout_height">100dp</item>
</style>
just change the size depending on the screen you are working with, then in the layout.xml add this:
<ImageView
android:id="#+id/imageSD"
style="#style/ImageSize" />
<TextView
android:id="#+id/imageNameSD"
style="#style/BigTextStyle" />
I believe you can use this resource alias sir.
Suppose you have two different images for sw320dp and sw600dp.
image1_sw320dp.png
image1_sw600dp.png
Put all image resource to folder drawable.
The in the folder values-sw320dp, create an xml resource. (also maybe you need for values-small, just copy the xml from values-320dp)
<resources>
<item type="drawable" name="image1">#drawable/image1_sw320dp</item>
</resources>
In folder values-sw600dp, create an xml resource.
<resources>
<item type="drawable" name="image1">#drawable/image1_sw600dp</item>
</resources>
Then use on the activity with R.drawable.image1. This can prevent for creating duplicate resources for example sw320dp, small, and normal.
Mr Rotary has a good way to work with multiple screen size.
Furthermore You can use Fragment in your application.
You can learn how to use fragment here : http://developer.android.com/guide/components/fragments.html

Categories

Resources