5

我想以SeekBar编程方式在画布上绘制一个。我编写了代码来设置SeekBar基于设备密度的 LayoutParams。我正在使用具有设备密度的开关盒,例如

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);

        }

但这不适用于三星 Note 5、Galaxy S6 Edge 等高端设备。我相信这些设备的密度范围为 XXXHIGH,那么为什么这不起作用?在画布上绘图时,设备密度和屏幕尺寸之间有什么关系吗?任何帮助将不胜感激。

4

3 回答 3

2

问题是这个问题没有任何通用代码。
如果您想要原始密度,则​​可以分别使用metrics.xdpimetrics.ydpi用于水平和垂直密度。

或遵循以下代码:

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";
    }

这个人在这里给出了这个主题的非常深入的解释:

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

还可以查看Android 开发者文档中的DisplayMetrics部分

于 2016-06-27T12:06:42.423 回答
2

您为什么不尝试摆脱所有if else案例并制作一些通用的东西?由于需要根据屏幕大小放置不同的像素值,所以可以dp改用。

您可以px根据dp设备的屏幕密度获取并在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;
}

所以你会创建param这样的:

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

whereDP_VALUE将在所有设备上保持不变。

我希望这可以解决您的问题。

于 2016-07-03T18:59:36.447 回答
1

如果您在画布上工作,我建议您只使用像素。您可以根据需要使用百分比宽度和高度来代替 dpi。这将最适合并适用于每台设备。例如,如果您需要600 x 128px屏幕尺寸的搜索栏800 x 1280 px。然后它就像宽度的 75% 和高度的 10%。现在通过代码应用这个百分比 -

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

这将完美地适用于所有屏幕尺寸。如果需要进一步帮助,请告诉我:)

于 2016-07-04T07:12:05.843 回答