Putting screen densities into the correct bucket

前端 未结 6 2223
滥情空心
滥情空心 2020-12-01 01:39

A set of six generalized densities:

ldpi (low) ~120dpi
mdpi (medium) ~160dpi
hdpi (high) ~240dpi
xhdpi (extra-high) ~320dpi
xxhdpi (extra-extra-high) ~480dpi         


        
6条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-01 02:10

    Bit late, but this may be useful to other readers. Screen density and the "bucket" Android uses to pick a resource from can be confusing. Google's documentation is pretty dense, and it takes alot of work to distill it down to something useful when writing code. Partly because there are several factors and they're telling you everything about screen density and dips. But the short answer is this.

    Basically, dpi is your defining factor, (if you rely on other factors like small/medium/large), this is not your answer. Otherwise, I found this answer quite helpful and simple. Here is some code I have collated from various sources that I run on app startup to determine display information.

    The screen density tells me what dpi level the device supports.

    float density = context.getResources().getDisplayMetrics().density;
    

    Next I have a simple device metrics method to tell me about the screen. (Note, I am using Timber logger).

    protected static void checkDeviceSize(AppCompatActivity context) {
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        Display display = context.getWindowManager().getDefaultDisplay();
        DisplayMetrics outMetrics = new DisplayMetrics();
        display.getMetrics(outMetrics);
    
        float density = context.getResources().getDisplayMetrics().density;
        float dpHeight = outMetrics.heightPixels / density;
        float dpWidth = outMetrics.widthPixels / density;
        String dpiName = getDpiName(density);
        Timber.e("density  :" + density + " [" + dpiName + "]");
        Timber.e("height dp:" + dpHeight + ", (" +outMetrics.heightPixels + "px)");
        Timber.e("width dp :" + dpWidth + ", (" + outMetrics.widthPixels + "px)");
    
    }
    

    I also have this simple helper method that determines the DPI name to support the method above.

    public static final String DPI_LDPI = "ldpi";
    public static final String DPI_MDPI = "mdpi";
    public static final String DPI_HDPI = "hdpi";
    public static final String DPI_XHDPI = "xhdpi";
    public static final String DPI_XXHDPI = "xxhdpi";
    public static final String DPI_XXXHDPI = "xxxhdpi";
    public static final String DPI_TVDPI = "tvdpi";
    
    private static String getDpiName(float density) {
        String result = "undefined";
        if (density < 1.0) {
            result = DPI_LDPI;
        } else if (density == 1.0f) {
            result = DPI_MDPI;
        } else if (density <= 1.3f) {
            result = DPI_TVDPI;
        } else if (density <= 1.5f) {
            result = DPI_HDPI;
        } else if (density <= 2.0f) {
            result = DPI_XHDPI;
        } else if (density <= 3.0f) {
            result = DPI_XXHDPI;
        } else if (density <= 4.0f) {
            result = DPI_XXXHDPI;
        }
        return result;
    }
    

    Finally this video from 2013 is still relevant today.

提交回复
热议问题