0

I want to call gray (sw320dp) layout file

Layout:- activity_main(sw320dp)

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate (Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main(sw320dp));
 }
}

enter image description here

  • This all layouts are designed as per the device resolution(height and width). Each and every layout will be called automatically whicherver will match with the configuration. You don't have to do anything explicitly to show up a particular layout file – primo Nov 27 '21 at 12:15
  • It will called automatically based on device resolution .If you want to call same Layout:- activity_main(sw320dp) then you need to delete all others layout like Layout:- activity_main(sw600dp) , Layout:- activity_main(sw480dp) etc then automatically it will call only Layout:- activity_main(sw320dp) – Mohammad Arman Nov 27 '21 at 12:36
  • 1
    but I want to call activity_main(sw320dp) layout support all devices As we are showing in java code –  Nov 27 '21 at 14:30
  • There's a way to achieve that, but it's kinda hacky. Why would you want to do it? – cmak Nov 27 '21 at 22:58
  • what is that way! –  Nov 27 '21 at 23:02
  • @vishalJenny But could you provide more details about your problem? I'm asking for curiosity but also to provide a better answer – cmak Nov 28 '21 at 16:03
  • @vishalJenny I updated my answer. But, again, without more details about your problem, I can't be more helpful. – cmak Nov 29 '21 at 21:12

1 Answers1

0

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.

  1. Get the uri of the resource file:

    String uriPath = "android.resource://" + getPackageName() + "/layout-sw320dp/main_activity";
    Uri uri = Uri.parse(uriPath);
    
  2. 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);
    
  3. 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.

cmak
  • 576
  • 1
  • 4
  • 15