ตั้งค่าความสูงของ LayoutParams โดยทางโปรแกรมเป็นพิกเซลที่ไม่ขึ้นกับความหนาแน่น


123

มีวิธีใดบ้างในการตั้งค่าความสูง / ความกว้างของLayoutParamsเป็นพิกเซลที่ไม่ขึ้นกับความหนาแน่น (dp) ดูเหมือนว่าความสูง / ความกว้างเมื่อตั้งค่าโดยใช้โปรแกรมจะเป็นพิกเซลและไม่ใช่ dp

คำตอบ:


271

คุณต้องแปลงค่า dip ของคุณเป็นพิกเซล:

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

สำหรับฉันนี่เป็นเคล็ดลับ


10
ฉันคิดว่า getActivity (). getResources (). getDimension (resourceID) ทำการแปลงที่ถูกต้อง
StErMi

3
ใช้ได้กับฉัน แต่มันแตกต่างกัน ... ถ้าฉันตั้งค่าความกว้าง / ความสูงของ ImageView โดยใช้วิธีการด้านบนเทียบกับการใช้ xml ใน XML ฉันตั้งค่า 85dp ในขณะที่วิธีการด้านบนต้องการ "75" เพื่อสร้างขนาดเดียวกัน มีความคิดว่าทำไม?
Dirk

1
@Dirk อาจมีปัญหาช่องว่างภายใน / ระยะขอบเมื่อคุณตั้งค่าโดยใช้โปรแกรม (โดยปกติคุณต้องระบุช่องว่างภายในด้วยตัวเองเมื่อคุณตั้งค่าในรหัส) ไม่ควรมีความแตกต่างระหว่างการตั้งค่า dp ใน XML หรือในโค้ด
Tiago

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

เรียกฟังก์ชันเช่นนี้

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

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

นั่นคือ ... คิดผิดจริงๆ คุณได้กำหนดฮาร์ดโค้ดเพื่อรองรับเฉพาะความหนาแน่นคงที่เท่านั้น หากคุณต้องการปรับขนาดตามปัจจัยการปรับความหนาแน่นให้คูณด้วยdeveloper.android.com/reference/android/util/…ซึ่งจะเหมือนกับการทำ (size * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT
hackbod

1
ใช่คำตอบใหม่ของคุณมีเหตุผล หรืออย่างที่บอกก็แค่คูณด้วย metrics.density นั่นคือสิ่งที่มีไว้สำหรับ
hackbod

6

เนื่องจากอาจใช้หลายครั้ง:

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

ฉันพบว่าการใช้อัตราการแปลงเป็นประโยชน์มากกว่าเนื่องจากต้องมีการแปลงค่ามากกว่าหนึ่งค่า เนื่องจากอัตราการแปลงไม่เปลี่ยนแปลงจึงช่วยประหยัดเวลาในการประมวลผลเล็กน้อย

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

นี่คือตัวอย่างข้อมูลของฉัน:

public class DpiUtils {

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

}

ที่ไหน DisplayMetrics metrics = getResources().getDisplayMetrics()


0

วิธีแก้ปัญหาที่ตอบไม่ได้ผลสำหรับฉันความสูงของมุมมองยังคงปิดอยู่ ฉันลงเอยด้วยสิ่งนี้ซึ่งได้ผลดี:

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

และถ้าคุณต้องการอีกทางหนึ่งพิกเซลเป็น dp ...

protected float px2dp(float px){
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float dp = px / (metrics.densityDpi / 160f);
    return Math.round(dp);
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.