Setel tinggi secara terprogram pada LayoutParams sebagai piksel yang tidak bergantung kepadatan


123

Apakah ada cara untuk menyetel tinggi / lebar LayoutParams sebagai piksel yang tidak bergantung kepadatan (dp)? Sepertinya tinggi / lebar, jika disetel secara terprogram, dalam piksel dan bukan dp.

Jawaban:


271

Anda perlu mengubah nilai dip Anda menjadi piksel:

int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, <HEIGHT>, getResources().getDisplayMetrics());

Bagi saya ini berhasil.


10
Saya pikir getActivity (). GetResources (). GetDimension (resourceID) melakukan operasi konversi yang benar.
— StErMi

3
Berfungsi untuk saya, tetapi berbeda ... jika saya menyetel lebar / tinggi ImageView menggunakan metode di atas vs. menggunakan xml. Dalam XML saya menetapkan 85dp sedangkan metode di atas membutuhkan "75" untuk menghasilkan ukuran yang sama. Tahu kenapa?
— Dirk

1
@Dirk Mungkin ada masalah padding / margin saat Anda menyetelnya secara terprogram (biasanya Anda harus menentukan sendiri padding saat Anda menyetel kode). Seharusnya tidak ada perbedaan apapun antara menyetel dp dalam XML atau dalam kode.
— Tiago

11
 public static int getDPI(int size, DisplayMetrics metrics){
     return (size * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT;        
 }

Panggil fungsi seperti ini,

DisplayMetrics metrics;
metrics = new DisplayMetrics();         
getWindowManager().getDefaultDisplay().getMetrics(metrics);

int heigh = getDPI(height or width, metrics);

Itu ... sangat salah. Anda memiliki hard-code untuk hanya mendukung jumlah kepadatan yang tetap. Jika Anda ingin menskalakan dengan faktor penskalaan kepadatan, kalikan saja dengan developer.android.com/reference/android/util/… yang juga akan sama dengan melakukan (size * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT.
— hackbod

1
Ya, jawaban baru Anda masuk akal. Atau seperti yang saya katakan, kalikan saja dengan metrics.density. Untuk itulah.
— hackbod

6

Karena dapat digunakan beberapa kali:

public static int convDpToPx(Context context, float dp) {
    DisplayMetrics metrics = context.getResources().getDisplayMetrics();
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, metrics);
}

Saya merasa lebih praktis menggunakan rasio konversi, karena biasanya lebih dari satu nilai harus dikonversi. Karena tingkat konversi tidak berubah, ini menghemat sedikit waktu pemrosesan.

/**
 * Get conversion rate from dp into px.<br>
 * E.g. to convert 100dp: px = (int) (100 * convRate);
 * @param context e.g. activity
 * @return conversion rate
 */
public static float convRateDpToPx(Context context) {
    return context.getResources().getDisplayMetrics().densityDpi / 160f;
}

5

Ini potongan saya:

public class DpiUtils {

    public static int toPixels(int dp, DisplayMetrics metrics) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, metrics);
    }

}

dimana DisplayMetrics metrics = getResources().getDisplayMetrics()


0

Solusi yang dijawab tidak berhasil untuk saya, ketinggian pandangan masih mati. Saya berakhir dengan ini, yang berfungsi dengan baik:

protected int dp2px(int dp){
    final float scale = getResources().getDisplayMetrics().density;
    return (int) (dp * scale + 0.5f);
}

Dan jika Anda ingin sebaliknya, piksel menjadi dp ...

protected float px2dp(float px){
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float dp = px / (metrics.densityDpi / 160f);
    return Math.round(dp);
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.