Рисование на холсте проблема в устройствах высокого класса
Я хочу нарисовать SeekBar
на холсте программно. Я написал код для установки параметров компоновки SeekBar
на основе плотности устройства. Я использую корпус переключателя с плотностью устройства, такой как
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);
}
Но это не работает в устройствах высокого класса, таких как Samsung Note 5, Galaxy S6 Edge и т. д..Я считаю, что эти устройства входят в диапазон плотности XXXHIGH, тогда почему это не работает?? Существует ли какая-либо связь между плотностью устройства и размером экрана при рисовании на холсте? Любая помощь будет очень кстати оцененный.3 ответа:
Почему бы вам не попытаться избавиться от всех случаев
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);
, где
Я надеюсь, что это может решить вашу проблему.DP_VALUE
останется постоянным для всех устройств.
Проблема в том, что нет никакого общего кода для этой проблемы.
Если вы хотите исходную плотность, то вы можете использовать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"; }
Очень глубокое объяснение этой темы дано этим парнем здесь:
Https://stackoverflow.com/a/33789580/5476209
Также проверьте раздел DisplayMetrics в документации для разработчиков Android
Если вы работаете на холсте, моя рекомендация играть только с пикселями. Вместо 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;
И это будет работать для всех размеров экрана идеально. Дайте мне знать в случае дальнейшей помощи:)