Saya telah menciptakan aplikasi saya dengan tinggi dan lebar yang diberikan dalam piksel untuk Pantech perangkat dan resolusi 480x800.
Saya perlu untuk mengubah tinggi dan lebar untuk G1 perangkat. Saya pikir mengubahnya menjadi dp akan memecahkan masalah dan memberikan solusi yang sama untuk kedua perangkat.
Apakah ada cara mudah untuk mengkonversi piksel untuk dp? Ada saran?
/**
* This method converts dp unit to equivalent pixels, depending on device density.
*
* @param dp A value in dp (density independent pixels) unit. Which we need to convert into pixels
* @param context Context to get resources and device specific display metrics
* @return A float value to represent px equivalent to dp depending on device density
*/
public static float convertDpToPixel(float dp, Context context){
return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
/**
* This method converts device specific pixels to density independent pixels.
*
* @param px A value in px (pixels) unit. Which we need to convert into db
* @param context Context to get resources and device specific display metrics
* @return A float value to represent dp equivalent to px value
*/
public static float convertPixelsToDp(float px, Context context){
return px / ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
Sebaiknya dimasukkan ke dalam Util.java kelas
public static float dpFromPx(final Context context, final float px) {
return px / context.getResources().getDisplayMetrics().density;
}
public static float pxFromDp(final Context context, final float dp) {
return dp * context.getResources().getDisplayMetrics().density;
}
float density = context.getResources().getDisplayMetrics().density;
float px = someDpValue * density;
float dp = somePxValue / density;
kepadatan
sama dengan
.75
on ldpi
(120
dpi) 1.0
on mdpi
(160
dpi; baseline)1.5
on hdpi
(240
dpi)2.0
pada xhdpi
(320
dpi) 3.0
on xxhdpi
(480
dpi) 4.0
on xxxhdpi
(640
dpi) Gunakan ini converter online untuk bermain-main dengan nilai-nilai dpi.
EDIT:
Tampaknya tidak ada hubungan 1:1 antara dpi
ember dan kepadatan
. Sepertinya Nexus 5X
menjadi xxhdpi
memiliki kepadatan
nilai 2.625
(bukan 3
). Lihat sendiri di Perangkat Metrik.
Jika anda dapat menggunakan dimensi XML itu's sangat sederhana!
Dalam res/values/dimens.xml
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="thumbnail_height">120dp</dimen>
...
...
</resources>
Kemudian di Jawa:
getResources().getDimensionPixelSize(R.dimen.thumbnail_height);
Anda dapat menggunakan ini .. tanpa Konteks
public static int pxToDp(int px) {
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
public static int dpToPx(int dp) {
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
Seperti @Stan disebutkan .. menggunakan pendekatan ini dapat menyebabkan masalah jika sistem perubahan densitas. Jadi harus tahu itu!
Secara pribadi saya menggunakan Konteks untuk melakukan itu. It's just another pendekatan yang saya ingin berbagi dengan anda
Menurut Android Panduan Pengembangan:
px = dp * (dpi / 160)
Namun seringkali anda'll ingin melakukan hal ini dengan cara lain ketika anda menerima sebuah desain yang's dinyatakan dalam satuan piksel. Jadi:
dp = px / (dpi / 160)
Jika anda're pada 240dpi perangkat rasio ini adalah 1.5 (seperti yang dinyatakan sebelumnya), jadi ini berarti bahwa 60px ikon sama dengan 40dp dalam aplikasi.
Tanpa Konteks
, elegan metode statis:
public static int dpToPx(int dp)
{
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
public static int pxToDp(int px)
{
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
Oleh karena itu anda dapat menggunakan berikut perumus untuk menghitung jumlah yang tepat dari piksel dari dimensi yang ditentukan dalam dp
public int convertToPx(int dp) {
// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
return (int) (dp * scale + 0.5f);
}
Bagi siapa saja yang menggunakan Kotlin:
val Int.toPx: Int
get() = (this * Resources.getSystem().displayMetrics.density).toInt()
val Int.toDp: Int
get() = (this / Resources.getSystem().displayMetrics.density).toInt()
Penggunaan:
64.toPx
32.toDp
menggunakan kotlin-ekstensi membuatnya lebih baik
fun Int.toPx(context: Context): Int = (this * context.resources.displayMetrics.density).toInt()
fun Int.toDp(context: Context): Int = (this / context.resources.displayMetrics.density).toInt()
UPDATE:
Karena displayMetrics
adalah bagian dari global sumber Daya bersama, kita dapat menggunakan sumber Daya.getSystem()`
fun Int.toPx(): Int = (this * Resources.getSystem().displayMetrics.density).toInt()
fun Int.toDp(): Int = (this / Resources.getSystem().displayMetrics.density).toInt()
Ini akan memberikan anda konversi dp untuk piksel:
public static int dpToPx(int dp)
{
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
Ini akan memberikan anda kode piksel konversi untuk dp:
public static int pxToDp(int px)
{
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
fun convertDpToPixel(dp: Float, context: Context): Float {
return dp * (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}
fun convertPixelsToDp(px: Float, context: Context): Float {
return px / (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}
public static float convertDpToPixel(float dp, Context context) {
return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
public static float convertPixelsToDp(float px, Context context) {
return px / ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
Mungkin cara terbaik jika anda memiliki dimensi dalam nilai-nilai/dimen adalah untuk mendapatkan dimensi langsung dari getDimension() metode ini akan mengembalikan anda dimensi sudah dikonversi ke nilai pixel.
context.getResources().getDimension(R.dimen.my_dimension)
Hanya untuk lebih menjelaskan hal ini,
getDimension(int resourceId)
akan kembali dimensi yang sudah dikonversi ke pixel SEBAGAI PELAMPUNG.
getDimensionPixelSize(int resourceId)
akan kembali sama tapi dipotong ke int, jadi SEBAGAI Bilangan BULAT.
Lihat Android referensi
public static int dp2px(Resources resource, int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,resource.getDisplayMetrics());
}
public static float px2dp(Resources resource, float px) {
return (float) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px,resource.getDisplayMetrics());
}
di mana sumber daya konteks.getResources().
Lebih elegan dengan menggunakan pendekatan kotlin's ekstensi fungsi
/**
* Converts dp to pixel
*/
val Int.dpToPx: Int get() = (this * Resources.getSystem().displayMetrics.density).toInt()
/**
* Converts pixel to dp
*/
val Int.pxToDp: Int get() = (this / Resources.getSystem().displayMetrics.density).toInt()
Penggunaan:
println("16 dp in pixel: ${16.dpToPx}")
println("16 px in dp: ${16.pxToDp}")
seperti ini:
public class ScreenUtils {
public static float dpToPx(Context context, float dp) {
if (context == null) {
return -1;
}
return dp * context.getResources().getDisplayMetrics().density;
}
public static float pxToDp(Context context, float px) {
if (context == null) {
return -1;
}
return px / context.getResources().getDisplayMetrics().density;
}
}
tergantung pada Konteks, kembali float nilai, metode statis
Dalam kasus anda mengembangkan kinerja kritis aplikasi, silakan mempertimbangkan berikut dioptimalkan kelas:
public final class DimensionUtils {
private static boolean isInitialised = false;
private static float pixelsPerOneDp;
// Suppress default constructor for noninstantiability.
private DimensionUtils() {
throw new AssertionError();
}
private static void initialise(View view) {
pixelsPerOneDp = view.getResources().getDisplayMetrics().densityDpi / 160f;
isInitialised = true;
}
public static float pxToDp(View view, float px) {
if (!isInitialised) {
initialise(view);
}
return px / pixelsPerOneDp;
}
public static float dpToPx(View view, float dp) {
if (!isInitialised) {
initialise(view);
}
return dp * pixelsPerOneDp;
}
}