It's recommended to use resource qualifiers, but there's a way to do it in code.
You could have all the layouts in the same folder (e.g. folder layout
) with the appropriate prefixes:
- activity_main_base.xml
- activity_main_svga.xml
- activity_main_sw320dp.xml
- (other layouts…)
Then in the onCreate
, you just have to get the one you want:
setContentView(R.layout.activity_main_sw320dp));
Now, if you need to select layouts depending on screen metrics…
by screen size:
int screenLayout = context.getResources().getConfiguration().screenLayout
&= Configuration.SCREENLAYOUT_SIZE_MASK;
switch (screenLayout) {
case Configuration.SCREENLAYOUT_SIZE_SMALL:
// small
break;
case Configuration.SCREENLAYOUT_SIZE_NORMAL:
// normal
break;
case Configuration.SCREENLAYOUT_SIZE_LARGE:
// large
break;
case Configuration.SCREENLAYOUT_SIZE_XLARGE:
// xlarge
break;
default:
// undefined
break;
}
by screen density:
int density = context.getResources().getDisplayMetrics().densityDpi;
switch (density) {
case DisplayMetrics.DENSITY_LOW:
// low ldpi
break;
case DisplayMetrics.SCREENLAYOUT_SIZE_NORMAL:
// medium mdpi
break;
case DisplayMetrics.SCREENLAYOUT_SIZE_LARGE:
// high hdpi
break;
case …:
// other densities (xhdpi, xxhdpi,…)
break;
default:
// undefined
break;
}
You can use some others like screen width or height and combine them as required.
EDIT:
Using the resource file directly is NOT POSSIBLE. Here's the research:
The idea is to attempt to get the file manually from the resources path, and then use XmlPullParser
to inflate the layout.
Get the uri of the resource file:
String uriPath = "android.resource://" + getPackageName() + "/layout-sw320dp/main_activity";
Uri uri = Uri.parse(uriPath);
Setup the XmlPullParser
object and pass it the uri:
XmlPullParser parser = Xml.newPullParser();
try {
InputStream in = getContentResolver().openInputStream(uri);
parser.setInput(in, "UTF-8");
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
parser.setFeature(XmlPullParser.FEATURE_VALIDATION, true);
parser.setFeature(XmlPullParser.FEATURE_REPORT_NAMESPACE_ATTRIBUTES, true);
} catch (Exception e) {
}
View layout = LayoutInflater.from(this).inflate(parser, null);
Finally set the layout as content view:
setContentView(layout);
But running this code will throw an InflateException
:
InflateException: Unexpected token (position:TEXT ������������P����...@3:312 in java.io.InputStreamReader@4009b5d)
That's because xml files inside resource folders (drawable
, layout
, etc. raw
is the exception) are encoded when compiling the app (using the Assets
folder should work)
So I'm afraid there's no way to do that.