Referencing another layout.xml file without duplicating it - android

I need to provide the same layout.xml file for an Activity for several different qualifiers. I know that there's a way to just reference one existing layout.xml instead of really copying it and having a duplicate one.
But how? Can't find it in the Android docs right now... :-/
Anybody faster than me?
EDIT: although I found this "solution" I am still not there.
<?xml version="1.0" encoding="utf-8"?>
<merge>
<include layout="#layout/main_ltr"/>
</merge>
I need to point to a different qualifiers's layout file, not to another layout file in the same qualifier.
Reason behind it: I specified the new Android 3.2 qualifier by proving screen width qualifiers. But on Android 3.0/3.1 this does not work, I need xlarge there, but I want it to be exactly the SAME file, not a copy!

If I understood correctly asker has one layout file for xlarge and sw-600dp and another one for all the rest. Anyway that was my situation when I stumbled on this question.
One can solve this by creating folders layout-xlarge and layout-s600dp and put one layout file in each but with the same contents. But one would like not to have two exact same files in two folders for obvious reasons.
This is my solution for the problem. Dont make layout-xlarge and layout-sw600dp files at all. Let's say you're creating a cool activity with layout file /res/layout/cool_activity.xml. Create your tablet layout file in the same folder but with a different name, i.e. /res/layout/cool_activity_for_tablet.xml and then create folders values-xlarge and values-sw600dp with layout.xml files in it with the following content
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="cool_activity" type="layout">#layout/cool_activity_for_tablet</item>
</resources>
Yes you will still have 2 of these with the same content but this is dumb content not the layout itself which can be hundreds of lines of xml.

<include> see Layout tricks #2
<merge> see Layout tricks #3

Create a wrapper layout my_activity.xml and your layouts for small and xlarge devices.
<merge>
<include layout="#layout/my_activity_small.xml"/>
</merge>
Your resources should look like:
layout
-> my_activity.xml
-> my_activity_small.xml
-> my_activity_xlarge.xml
Now override my_activity.xml in layout-xlarge and layout-sw600dp:
<merge>
<include layout="#layout/my_activity_xlarge.xml"/>
</merge>
Your ressources should look like:
layout
-> my_activity.xml <-- includes my_activity_small.xml
-> my_activity_small.xml
-> my_activity_xlarge.xml
layout-xlarge
-> my_activity.xml <-- includes my_activity_xlarge.xml
layout-sw600dp
-> my_activity.xml <-- includes my_activity_xlarge.xml
Use my_activity.xml in your code for loading the layout.
P.S.: You can not point to a layout in another qualifier's directory, as you mentioned in one of the comments.

Related

Use generic layout for top-level ar locale, but region specific locale for others

I'm developing a multilingual app and need to show a different layout for a specific region
My res structure is as follows
res/
layout/
questions.xml
layout-ar-rLY/
questions.xml
When the locale is English (en) the default layout is shown. When the locale is Libyan the Libyan (ar_LY) layout is shown. However, when the locale is Arabic (ar) the Libyan layout is still shown. I need it to show the default layout.
I know that I can simply create a layout-ar directory and copy the questions.xml layout there, however, I am wondering if there is a more elegant way to achieve the right result, so that I don't have to maintain both files.
res/
layout/
questions.xml
layout-ar/
questions.xml
layout-ar-rLY/
questions.xml
The best solution I have come up with so far is for the default and the Arabic layouts both to include a shared sub-layout. Is there a better way to achieve the same result?
Thanks to MH's comment above I had a look at the Android documentation on the official way to do this using Aliases which suggest this.
<?xml version="1.0" encoding="utf-8"?>
<merge>
<include layout="#layout/main_ltr"/>
</merge>
Unfortunately the method given in the documentation doesn't actually work (as detailed in this StackOverflow) answer. Using a merge tag as a root element gives an InflateException error.
I'm sure that the second suggested fix contained in the StackOverflow thread should work; however, the concept of placing Layouts into the resources seems to me to be just as flawed as creating multiple copies (ie from a maintenance perspective you have to remember they are there and not in the layouts folders where you'd expect them to be) so in the end I compromised on the following:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<include layout="#layout/questions_default"/>
</FrameLayout>
Which is a bit more verbose than just a merge tag, but at least it works.

How do I setup my fragments such that the layout I am using for phone also works well with tablets?

I am using my app currently ,made of fragments , just on phone. I am planning to add tablet version of the same , but seems like some fragments don't work exactly as expected on the tablet and often many mess up on landscape.So I just needed some pointers how to go about the same?
Here is my code for one of the fragments layout in xml :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/altercolor2" >
<HorizontalPageView
android:id="#+id/headline_gallery"
android:layout_width="match_parent"
android:layout_height="140dp" />
<include layout="#layout/loading_no_results" />
</FrameLayout>
How do I alter it such that the height even works on tablet as expected without cutting off some data? Also, should i add another duplicate layout somewhere for this or there's way around it? Any help appreciated,thanks!
Try this. Make a new layout-xlarge folder in /res directory and place all your tablet related xml files in that folder. Android system automatically fetches layout files from this layout-xlarge folder for 7-10 inch screens.
And to support landscape mode, design your layout files specifically for landscape mode and put it in layout-land folder. But make sure that the name of the files in all the folders are same.
Android Training guide covers this best.
You should read it
http://developer.android.com/guide/practices/screens_support.html#support
Theory, logic and best practices are a bit long to be explained here. So, my suggestion is to read this tutorial from the official documentation, http://developer.android.com/training/basics/fragments/index.html, checking all the topics and the links suggested by Google.
Also check the example application provided by them as well.
Having done that, if you have a more specific issue, please ask here and we will be more than happy to help you.
Try putting your main views i.e HorizontalPageView in a linear layout and make use of the weight and orientation attributes of the linear layout.
As I understand from your code you want to align the views vertically, in this case the "weight" attribute does wonders
first you need to figure out whether you will use a different ui for tablet version besides the phone version, if you use the same ui disign, (one pane or two panes), just thinking about portrait/landscape is enough, otherwise you need use style and value-swxxx to arrange the layout files for tablet and phone.
Besides the phone/tablet issue, you also need use layout-land to define the same layout unit for the landscape mode. so there are (phone-portrait, phone-landscape, tablet-portrait, tablet-landscape) four scenarios.

Is it possible to save layout_weight in an xml?

I need to change the layout_weight of 3 views in a layout, according to the physical size of the screen. The views have the weight of 0-1-0, but this has to change to 0.2-0.6-0.2 when the layout is used in an xlarge screen.
I tried saving the layout_weight inside different copies of the dimensions.xml (one in values/dimensions and an other one in values-xlarge/dimensions), but it looks like I cannot give a dimension without setting dp/px or w/e (cannot save a "raw" number like 1, or 0.2).
Is it possible to do via xml somehow, or do I have to work programmatically in order to achieve that?
Try an integer resource file. It is very similar to dimensions.
http://developer.android.com/guide/topics/resources/more-resources.html
Create a file in your corresponding values folders i.e. values, values-large, values-xlarge, .... Add a resources file with content similar to this example:
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<item type="integer" name="layout_weight_xy">7</item>
</resources>
and then call
android:layout_weight="#integer/layout_weight_xy"
in your layout file.
You can create special layout in layout-xlarge folder and provide different weights there
First, define your resource e.g integer.xml and make sure you set the correct type and format. If you want to use it for layout_weight you can set type="integer" format="float".
<item name="my_weight_value" type="integer" format="float">1.2</item>
Then we can use it in layout
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="#integer/my_weight_value"
android:orientation="vertical">
</LinearLayout>

Will including an Android layout choose between hdpi/mdpi/ldpi layouts as for full layouts?

Suppose I have a layout in the main, non-DPI specific layout resource folder, and that layout does an <include> of a sub layout that exists in both the hdpi/mdpi/ldpi folders. Can I expect the final inflated layout to aggregate either the h/m/l-dpi sub layout depending on the device DPI, just as for "full" layouts?
Thanks!
Whereas at the time of the post I did not have an opportunity to test out the proposition of the post, I have since had a chance to do so, and thus will answer my own question, since noone else has done so.
Yes, the following scenario works as expected (tested at API level 8):
layout/main.xml:
... <include layout="#layout/included"/> ...
layout/included.xml:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="GENERIC included fragment"/>
</merge>
layout-ldpi/included.xml:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LOW-DPI included fragment"/>
</merge>
Running the app on, say, a QVGA device renders a view in which the included part is from the LDPI directory as desired, whereas a non LDPI device grabs the default one from the layout directory.

using merge with layouts giving error for one file, no error on other. same code!

I am creating a few layouts with the root element being merge. inside the merge element i have a ScrollView containing a TextView. Here is the file:
<?xml version="1.0" encoding="utf-8"?>
<merge
xmlns:android="http://schemas.android.com/apk/res/android">
<ScrollView
android:id="#+id/scroll"
android:padding="6dp"
android:layout_below="#id/headingLayout"
android:layout_above="#id/tabsLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/aboutTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</ScrollView>
</merge>
I am getting 2 errors: there is no resource to match the layout_below and layout_above names i have put in.
I have another layout xml file including very similar components, some of which also reference #id/headingLayout and #id/tabsLayout. Both of these XML layout files do not contain the component with name headingLayout or tabsLayout
Why is it that one layout file has no errors about these references and the other layout file does? What the crap am i doing wrong, the app will build and run like i expect, until i add this merge to another layout?
I have even tried copying the xml from the working layout file, to find that it gives the same errors, something must be wrong with my new layout file. I have tried cleaning, rebuilding, opening/closing eclipse..
Wow, this is a strange fix i have found for this. the layout i have given in my question above(the one giving errors) is named about.xml. the layout with no errors which also includes merge and references to other xml components is named home.xml. the xml file including the referenced components is named base_layout.xml.
in the eclipse Package Explorer under the layout folder, items are listed alphabetically. so the home.xml file came after base_layout.xml, and could therefore reference the components inside it. Since about.xml came before base_layout.xml, about.xml could not reference anything inside base_layout.xml.
so i just renamed base_layout.xml to aaa_base_layout.xml so it would be first, and all errors go away.

Categories

Resources