Lập trình đặt chiều cao trên LayoutParams dưới dạng pixel độc lập với mật độ


123

Có cách nào để đặt chiều cao / chiều rộng của LayoutParams thành pixel độc lập với mật độ (dp) không? Có vẻ như chiều cao / chiều rộng, khi được đặt theo chương trình, được tính bằng pixel chứ không phải dp.

Câu trả lời:


271

Bạn cần chuyển đổi giá trị nhúng của bạn thành pixel:

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

Đối với tôi điều này không có mẹo.


10
Tôi nghĩ rằng getActivity (). GetResource (). GetDimension (resourceID) thực hiện các hoạt động chuyển đổi chính xác.
StErMi

3
Hoạt động với tôi, nhưng nó khác ... nếu tôi đặt chiều rộng / chiều cao của ImageView bằng phương pháp trên so với sử dụng xml. Trong XML tôi đặt 85dp trong khi phương thức trên cần "75" để tạo cùng kích thước. Bất cứ ý tưởng tại sao?
Dirk

1
@Dirk Có thể có vấn đề về phần đệm / lề khi bạn đặt nó theo chương trình (thông thường bạn phải tự chỉ định phần đệm khi bạn đặt mã). Không nên có sự khác biệt nào giữa việc đặt dp trong XML hoặc trong mã.
Tiago

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

Gọi hàm như thế này,

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

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

Điều đó ... thực sự sai. Bạn đã mã hóa cứng để chỉ hỗ trợ một số mật độ cố định. Nếu bạn muốn chia tỷ lệ theo hệ số tỷ lệ mật độ, chỉ cần nhân với developer.android.com/reference/android/util/ , điều này cũng sẽ giống như làm (size * metrics.d mậtDpi) / DisplayMetrics.DENSITY_DEFAULT.
hackbod

1
Có câu trả lời mới của bạn là hợp lý. Hoặc như tôi đã nói, chỉ cần nhân với metrics.d mật. Đó là những gì nó cho.
hackbod

6

Vì nó có thể được sử dụng nhiều lần:

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

Tôi thấy thực tế hơn khi sử dụng tỷ lệ chuyển đổi, vì thông thường hơn một giá trị phải được chuyển đổi. Vì tỷ lệ chuyển đổi không thay đổi, nó tiết kiệm một chút thời gian xử lý.

/**
 * 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

Đây là đoạn trích của tôi:

public class DpiUtils {

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

}

Ở đâu DisplayMetrics metrics = getResources().getDisplayMetrics()


0

Giải pháp trả lời không hiệu quả với tôi, chiều cao của chế độ xem vẫn bị tắt. Tôi đã kết thúc với điều này, hoạt động tốt:

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

Và nếu bạn muốn làm tròn theo cách khác, pixel sẽ ...

protected float px2dp(float px){
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float dp = px / (metrics.densityDpi / 160f);
    return Math.round(dp);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.