Drawing on Canvas issue in high end devices

二次信任 提交于 2019-12-07 05:23:53

问题


I want to draw a SeekBar on canvas programmatically. I wrote code to set the LayoutParams of the SeekBar based on device density. I am using switch case with device density like

final DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
if(metrics.densityDpi <= DisplayMetrics.DENSITY_LOW){
        zoomBarParams = new LinearLayout.LayoutParams(18,
                LayoutParams.FILL_PARENT);
        } else if (metrics.densityDpi <= DisplayMetrics.DENSITY_MEDIUM){
            zoomBarParams = new LinearLayout.LayoutParams(24,
                    LayoutParams.FILL_PARENT);

        }else if (metrics.densityDpi <= DisplayMetrics.DENSITY_HIGH){
            zoomBarParams = new LinearLayout.LayoutParams(24,
                    LayoutParams.FILL_PARENT);

        }else if (metrics.densityDpi <= DisplayMetrics.DENSITY_XHIGH){
            zoomBarParams = new LinearLayout.LayoutParams(31,
                    LayoutParams.FILL_PARENT);


        }else if (metrics.densityDpi <= DisplayMetrics.DENSITY_XXHIGH){
            zoomBarParams = new LinearLayout.LayoutParams(60,
                    LayoutParams.FILL_PARENT);

        }else if (metrics.densityDpi <= DisplayMetrics.DENSITY_XXXHIGH){
            zoomBarParams = new LinearLayout.LayoutParams(60,
                    LayoutParams.FILL_PARENT);

        } else {
            zoomBarParams = new LinearLayout.LayoutParams(60,
                    LayoutParams.FILL_PARENT);

        }

But this isn't working in high end devices like Samsung Note 5, Galaxy S6 Edge etc..I believe that these devices comes in the density range XXXHIGH, then why is this not working?? Is there any relation between device density and screen size while drawing on canvas? Any help will be greatly appreciated.


回答1:


Why don't you try to get rid of all the if else cases and make something generic? Since you need to put different pixel values depending on the screen size, you can use dp instead.

You can get px from dp depending on the screen density of the device and use that in LayoutParams.

public static float convertDpToPixel(float dp, Context context){
    Resources resources = context.getResources();
    DisplayMetrics metrics = resources.getDisplayMetrics();
    float px = dp * ((float)metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT); // You can cache "((float)metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT)" to avoid re-calculation.
    return px;
}

So you will create the param like this:

zoomBarParams = new LinearLayout.LayoutParams(convertDpToPixel(DP_VALUE, context),
                LayoutParams.FILL_PARENT);

where DP_VALUE will remain constant across all devices.

I hope this might solve your problem.




回答2:


Problem is there is not any generic code for this problem.
If you want original density then you can use metrics.xdpi and metrics.ydpi for horizontal and vertical density respectively.

or go follow this code:

public static String getDensity(Resources resources) {
    switch (resources.getDisplayMetrics().densityDpi) {
        case DisplayMetrics.DENSITY_LOW:
            return "ldpi";
        case DisplayMetrics.DENSITY_MEDIUM:
            return "mdpi";
        case DisplayMetrics.DENSITY_HIGH:
            return "hdpi";
        case DisplayMetrics.DENSITY_XHIGH:
            return "xhdpi";
        case DisplayMetrics.DENSITY_XXHIGH:
            return "xxhdpi";
        case DisplayMetrics.DENSITY_XXXHIGH:
            return "xxxhdpi";
        case DisplayMetrics.DENSITY_TV:
            return "tvdpi";
        default:
            return "unknown";
    }

A very depth explanation of this topic is given by this guy here :

https://stackoverflow.com/a/33789580/5476209

also check DisplayMetrics section in Android developers documentation




回答3:


If you are working on canvas, my recommendation to play with pixels only. In stead of dpi you can use percentage width and height according to your requirement. That will best suit and work on every device. For example if you need a seekbar of 600 x 128px for the screen size 800 x 1280 px. Then it is like 75% of width and 10% of height. Now apply this percentage by code-

DisplayMetrics dm = getResources().getDisplayMetrics();
int seekBarWidth= dm.widthPixels * 75 / 100;
int seekBarHeight= dm.heightPixels * 10 / 100;

And this will work for all screen sizes perfectly. Let me know in case of further assistance :)



来源:https://stackoverflow.com/questions/37988804/drawing-on-canvas-issue-in-high-end-devices

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!