Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android resource selection layout- and values- inconsistencies

The issue I am experiencing indicates that the resource bucket being selected for a given activity's layout XML is inconsistent with the resources being selected from the values folder despite the exact same resource qualifiers being used in each set of folders.

Example

After placing some logging code within my application's abstract parent activity I can see that when starting my application over a Nexus 7 type emulator (Android 4.1) the smallest width is indeed 600dp, the layout-sw600dp-* folder is being used to fetch the UI for the activity but the folder being used for the values is values-large-*. I was expecting this to be values-sw600dp-* thus providing me with the vital information as to what resource bucket the activity is running under.

Code doing the logging within my app's parent activity for all android.app.Activitys

  protected void onCreate(final Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     final Configuration config = getResources().getConfiguration();     Log.i(this.getClass().getSimpleName(), String.format("Smallest width is [%s]", config.smallestScreenWidthDp));     configurationContext = SupportedDeviceConfiguration.fromResourceQualifer(getString(string.resourceQualifier));     Log.i(this.getClass().getSimpleName(), String.format("Running under the [%s] configuration context.", configurationContext.getResourceQualifier())); ... 

Logging output from when I run this code on a Nexus 7 type device;

[Logging fluff] Smallest width is [600] [Logging fluff] Running under the [layout-large-land] configuration context. 

I know what you are thinking - where did that layout-large-land derivation come from? Read on...

Background

I am trialling an approach outlined here which would allow me to inspect the resources bucket under use at runtime. Essentially the approach I have implemented has the following structure of resource qualifiers;

- res   + layout                   // Default portrait layout.   + layout-land              // Default landscape layout   + layout-large-land        // pre 3.2 phablet landscape layout (Galaxy Note at v2.3.3)   + layout-xlarge-land       // pre 3.2 tablet landscape layout   + layout-xlarge-port       // pre 3.2 tablet portrait layout   + layout-sw520dp-port      // post 3.1 phablet portrait layout (Galaxy Note at v4.0.3)   + layout-sw520dp-land      // post 3.1 phablet landscape layout   + layout-sw600dp-port      // post 3.1 mini-tablet portrait layout (Nexus 7)   + layout-sw600dp-land      // post 3.1 mini-tablet-landscape layout    + layout-sw700dp-port      // post 3.1 tablet portrait layout   + layout-sw700dp-land      // post 3.1 tablet landscape layout   - values                   // Contains the root strings.xml      strings.xml   - values-land      default-config.xml               - values-large-land      default-config.xml           - values-xlarge-land      default-config.xml        - values-xlarge-port      default-config.xml        - values-sw520dp-port      default-config.xml        - values-sw520dp-land      default-config.xml        - values-sw600dp-port      default-config.xml        - values-sw600dp-land      default-config.xml        - values-sw700dp-port      default-config.xml        - values-sw700dp-land      default-config.xml 

So essentially the values qualifiers reflect that of the layout qualifiers. Under each of values-* folders I have defined a single XML file called device-config.xml with content;

<?xml version="1.0" encoding="utf-8"?> <resources>     <string name="resourceQualifier">layout-{qualifier of values folder}</string> </resources> 

So, for example the values-sw600dp-land folder's device-config.xml contains a single string with value layout-sw600dp-land. The objective here is for my code to remain in-sync with the resource layouts being displayed on screen. This is needed so that my code doesn't go off "finding by id" some item which doesn't exist on the displayed layout owing to the real-estate involved.

(Optional) Deeper reasoning for why I am doing this

The deeper reasoning for wanting to know the bucket being used at runtime was born out of the realisation that my single-fragment-for-all-configurations code was becoming difficult to manage with various switch based logic which was not transparent and often duplicated features from other layouts...it was as if I needed some sort of Fragment Inheritance ...which if you follow the link is exactly what I did. The downside of this is that I need to know what screen I am working with before instructing the framework to instantiate the x, y, or z fragment, safe in the knowledge that the Fragment being created will never be out of sync with the layout it is meant to inflate. This inheritance works and allows for a far more manageable fragment stack (Sonar is happier too which is nice).

Summary

However, I have been thwarted by this apparent discrepancy between which layout folder and values folder the framework selects. Each have the same qualifiers therefore why doesn't an Activity leveraging the layout-sw600dp-land UI XML use the values-sw600dp-land resource? I am hoping I've got something wrong because it was the neatest of the potential solutions posted on the SO discussion I linked to above.

like image 440
BrantApps Avatar asked Oct 18 '12 22:10

BrantApps


People also ask

What is the syntax for assigning values to attributes within a layout resource XML file?

Layout Binding expressions Expressions in the XML layout files are assigned to a value of the attribute properties using the “ @{} " syntax. We just need to use the basic syntax @{} in an assignment expression.

Which resource qualifier is used most frequently to select for tablets?

Smallest Screen Width: This qualifier is used most frequently to select for tablets. It is defined by the smallest width of the device (regardless of orientation), which removes the ambiguity when talking about “height” and “width” since some devices are traditionally held in landscape mode, and others in portrait.

What are resource configuration qualifiers in Android?

<qualifier> is a name that specifies an individual configuration for which these resources are to be used (defined in table 2).

What is res Android?

The res/values folder is used to store the values for the resources that are used in many Android projects to include features of color, styles, dimensions etc. Below explained are few basic files, contained in the res/values folder: colors.


2 Answers

I'm sure you're dealing with resource precedence used for selection.

If you provide folders:

layout-sw600dp-* values-large-* values-sw600dp-* 

Android is not obliged to match values selection folder to those of layout, rather it uses same precedence logic separately for layout and separately for values folder.

You can learn about this selection algorithm here: http://developer.android.com/guide/topics/resources/providing-resources.html#BestMatch

like image 66
Pointer Null Avatar answered Oct 04 '22 03:10

Pointer Null


I'm doing an app for android 4.0.3. if you use the sw600dp, sw720dp, It is neccesary to use the next?: - values-sw600dp-port default-config.xml
- values-sw600dp-land default-config.xml
- values-sw700dp-port default-config.xml
- values-sw700dp-land default-config.xml because I'm not using the res/values-XXX and it seems to works fine.

like image 21
Adrian Avatar answered Oct 04 '22 03:10

Adrian