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.

psikotik
sumber

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.

Mokus
sumber
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);
neraka
sumber
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;
}
Gunnar Bernstein
sumber
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()

Roma
sumber
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);
}
Tuan L
sumber