Building on Canvas Issue on High Performance Devices

I want to draw a SeekBar on a canvas programmatically. I wrote code to install LayoutParams SeekBar based on device density. I use a switch with a 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 does not work on top-level devices such as Samsung Note 5, Galaxy S6 Edge, etc. I believe these devices are in the XXXHIGH density range, then why doesn't it work? Is there a connection between the density of the device and the size of the screen when drawing on canvas? Any help would be greatly appreciated.

+5
source share
3 answers

Why don't you try to get rid of all cases of if else and do something in common? 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 it 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 param as follows:

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

where DP_VALUE will remain constant on all devices.

I hope this can solve your problem.

+2
source

The problem is that there is no common code for this problem.
If you want to have the original density, you can use metrics.xdpi and metrics.ydpi for horizontal and vertical density, respectively.

or execute the following 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 detailed explanation of this topic is given by this guy here:

fooobar.com/questions/182888 / ...

also check the DisplayMetrics section in the Android developer documentation

+2
source

If you work on canvas, my recommendation is to play with pixels only. Instead of dpi, you can use percentage width and height to suit your requirements. This works best and works on every device. For example, if a screen size of 800 x 1280 px requires an arrow of 600 x 128px . Then it looks like 75% of the width and 10% of the height. Now apply this percentage by code

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

And it will work great for all screen sizes. Let me know in case of further help :)

+1
source

All Articles