利用高端设备中的 Canvas 问题
Drawing on Canvas issue in high end devices
我想以编程方式在 canvas 上绘制 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,那为什么它不起作用?在canvas上绘图时设备密度和屏幕尺寸之间有什么关系吗?任何帮助将不胜感激。
问题是这个问题没有任何通用代码。
如果你想要原始密度,那么你可以使用 metrics.xdpi
和 metrics.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";
}
这家伙在这里给出了一个非常深入的解释:
还要检查 Android 开发人员文档中的 DisplayMetrics 部分
你为什么不尝试摆脱所有 if else
案例并制作一些通用的东西?由于您需要根据屏幕尺寸放置不同的像素值,因此您可以使用 dp
代替。
根据设备的屏幕密度,您可以从 dp
获得 px
,并在 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);
其中 DP_VALUE
将在所有设备上保持不变。
希望这可以解决您的问题。
如果您正在研究 canvas,我建议您只玩像素。您可以根据需要使用百分比宽度和高度来代替 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;
这将完美适用于所有屏幕尺寸。如果需要进一步帮助,请告诉我:)
我想以编程方式在 canvas 上绘制 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,那为什么它不起作用?在canvas上绘图时设备密度和屏幕尺寸之间有什么关系吗?任何帮助将不胜感激。
问题是这个问题没有任何通用代码。
如果你想要原始密度,那么你可以使用 metrics.xdpi
和 metrics.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";
}
这家伙在这里给出了一个非常深入的解释:
还要检查 Android 开发人员文档中的 DisplayMetrics 部分
你为什么不尝试摆脱所有 if else
案例并制作一些通用的东西?由于您需要根据屏幕尺寸放置不同的像素值,因此您可以使用 dp
代替。
根据设备的屏幕密度,您可以从 dp
获得 px
,并在 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);
其中 DP_VALUE
将在所有设备上保持不变。
希望这可以解决您的问题。
如果您正在研究 canvas,我建议您只玩像素。您可以根据需要使用百分比宽度和高度来代替 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;
这将完美适用于所有屏幕尺寸。如果需要进一步帮助,请告诉我:)