การแปลงพิกเซลเป็น dp


826

ผมได้สร้างแอพลิเคชันของฉันกับความสูงและความกว้างที่กำหนดในพิกเซลสำหรับอุปกรณ์ Pantech 480x800ที่มีความละเอียด

ฉันต้องการแปลงความสูงและความกว้างสำหรับอุปกรณ์ G1
ฉันคิดว่าการแปลงเป็น dp จะแก้ปัญหาและให้วิธีแก้ปัญหาเดียวกันสำหรับอุปกรณ์ทั้งสอง

มีวิธีง่าย ๆ ในการแปลงพิกเซลเป็น DP?
ข้อเสนอแนะใด ๆ


1
หากคุณกำลังมองหาการทำ one-off แปลง (เช่นสำหรับการส่งออกสไปรท์จาก Photoshop) นี่เป็นแปลงที่ดี
Paul Lammertsma


คำตอบ:


1037
// Converts 14 dip into its equivalent px
float dip = 14f;
Resources r = getResources();
float px = TypedValue.applyDimension(
    TypedValue.COMPLEX_UNIT_DIP,
    dip,
    r.getDisplayMetrics()
);

332
หมายเหตุ: ข้างต้นกำลังแปลง DIP เป็นพิกเซล คำถามเดิมถามวิธีแปลงพิกเซลเป็น Dips!
Eurig Jones

12
นี่คือคำตอบที่แท้จริงสำหรับ OP: stackoverflow.com/questions/6656540/…
qix

119
มันตลกดีที่คำตอบมีประโยชน์มากขึ้นเมื่อไม่ตอบคำถาม -_- ฉันคิดว่าฉันต้องการสิ่งที่คำถามถามแล้วฉันก็รู้ว่าฉันไม่ได้! คำตอบที่ดีมาก ฉันมีคำถาม ฉันจะรับพารามิเตอร์ตัวสุดท้ายได้applyDimensionอย่างไร ฉันสามารถทำได้getResource().getDisplayMetrics()หรือมีอะไรอีกบ้าง?
Andy

11
หมายเหตุ: การดำเนินการค่อนข้างแพง พยายามแคชค่าต่างๆให้เร็วขึ้น
Entreco

8
หากไม่มีการเข้าถึงการContextใช้วัตถุResources.getSystem().getDisplayMetrics()
Farshad Tahmasbi

871
/**
 * 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);
}

8
อาจจะคุ้มค่าที่จะส่งคืน Math.round int (px) เนื่องจากวิธีการส่วนใหญ่คาดหวังว่าค่าจำนวนเต็ม
Raj Labana

3
@MuhammadBabar นี่เป็นเพราะ 160 dpi (mdpi) เป็นความต้องการพื้นฐานที่การคำนวณความหนาแน่นอื่น ๆ ตัวอย่างเช่น hdpi นั้นถูกพิจารณาว่ามีความหนาแน่น 1.5 เท่าของ mdpi ซึ่งเป็นเพียงอีกวิธีหนึ่งในการพูด 240 dpi ดูคำตอบของ Zsolt Safrany ด้านล่างสำหรับความหนาแน่นทั้งหมด
สตีเฟ่น

19
@TomTasche: จากเอกสารสำหรับResource.getSystem()(การเน้นของฉัน): "ส่งคืนวัตถุทรัพยากรที่ใช้ร่วมกันทั่วโลกที่ให้การเข้าถึงทรัพยากรระบบเท่านั้น (ไม่มีทรัพยากรแอปพลิเคชัน) และไม่ได้กำหนดค่าสำหรับหน้าจอปัจจุบัน ( ไม่สามารถใช้หน่วยมิติไม่เปลี่ยนแปลง ขึ้นอยู่กับการปฐมนิเทศ ฯลฯ ) "
Vicky Chijwani

2
นักพัฒนามีทางเลือกที่จะเพดาน / ชั้นค่า มันเป็นการดีกว่าที่จะให้การควบคุมแก่นักพัฒนา
Muhammad Nabeel Arif

7
ฉันจะแนะนำและDisplayMetrics.DENSITY_DEFAULTแทนที่จะเป็น160f developer.android.com/reference/android/util/ …
milcaepsilon

285

ใส่ไว้ในคลาส Util.java โดยเฉพาะ

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;
}

5
สิ่งนี้ไม่สามารถใช้ได้กับอุปกรณ์ทั้งหมด! ผลลัพธ์ของคำตอบนี้เทียบกับการใช้ TypedValue.applyDimension ไม่เหมือนกันใน OnePlus 3T (อาจเป็นเพราะ OnePlus มีการปรับขนาดแบบกำหนดเองที่มีอยู่ในระบบปฏิบัติการ) การใช้ TypedValue.applyDimension ทำให้เกิดพฤติกรรมที่สอดคล้องกันในอุปกรณ์ต่างๆ
Ben De La Haye

197
float density = context.getResources().getDisplayMetrics().density;
float px = someDpValue * density;
float dp = somePxValue / density;

density เท่ากับ

  • .75บนldpi( 120dpi)
  • 1.0บนmdpi( 160dpi; พื้นฐาน)
  • 1.5บนhdpi( 240dpi)
  • 2.0บนxhdpi( 320dpi)
  • 3.0บนxxhdpi( 480dpi)
  • 4.0บนxxxhdpi( 640dpi)

ใช้ตัวแปลงออนไลน์นี้เพื่อเล่นด้วยค่า dpi

แก้ไข: ดูเหมือนว่าไม่มี 1: 1 ความสัมพันธ์ระหว่างถังและdpi densityดูเหมือนว่าสิ่งมีNexus 5Xชีวิตxxhdpiมีdensityค่าเป็น2.625(แทน3) ดูตัวเองในการวัดอุปกรณ์


3
"ดูเหมือนว่า Nexus 5X ที่ xxhdpi มีค่าความหนาแน่น 2.6 (แทนที่จะเป็น 3)" โดยทางเทคนิคแล้ว Nexus 5X คือ 420dpi และ Nexus 6 / 6P เป็น 560dpi ไม่ได้ลงจอดโดยตรงในถังมาตรฐานเช่นเดียวกับ Nexus 7 พร้อม TVdpi (213dpi) ดังนั้นไซต์ที่แสดงรายการเหล่านั้นเป็น xxdpi และ xxxhdpi จึงเป็นเรื่องตลก แผนภูมิของคุณถูกต้องและอุปกรณ์เหล่านั้นจะปรับขนาดตามที่เก็บ "พิเศษ" dpi อย่างเหมาะสม
Steven Byle

108

คุณสามารถใช้สิ่งนี้ .. โดยไม่มีบริบท

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);
}

ตามที่ @Stan กล่าวถึง .. การใช้วิธีการนี้อาจทำให้เกิดปัญหาหากระบบเปลี่ยนความหนาแน่น ดังนั้นจงระวังให้ดี!

โดยส่วนตัวฉันใช้บริบทเพื่อทำเช่นนั้น เป็นอีกแนวทางหนึ่งที่ฉันต้องการแบ่งปันให้คุณ


11
คุณอาจไม่ต้องการใช้สิ่งนี้ เอกสารประกอบสำหรับ getSystem () - "ส่งคืนวัตถุทรัพยากรที่ใช้ร่วมกันทั่วโลกที่ให้การเข้าถึงทรัพยากรระบบเท่านั้น (ไม่มีทรัพยากรแอปพลิเคชัน) และไม่ได้กำหนดค่าสำหรับหน้าจอปัจจุบัน (ไม่สามารถใช้หน่วยมิติไม่เปลี่ยนแปลงตามการวางแนว ฯลฯ ) ."
สแตน

สิ่งที่สองที่ @Stan กำลังพูดคือ: สิ่งนี้เป็นอันตรายและคุณไม่ควรใช้งานโดยเฉพาะอย่างยิ่งตอนนี้เมื่อปัจจัยรูปแบบของอุปกรณ์มีความซับซ้อน
Saket

93

หากคุณสามารถใช้ขนาด XML มันง่ายมาก!

ในres/values/dimens.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="thumbnail_height">120dp</dimen>
    ...
    ...
</resources>

จากนั้นใน Java ของคุณ:

getResources().getDimensionPixelSize(R.dimen.thumbnail_height);

เนื่องจาก px to dp ขึ้นอยู่กับความหนาแน่นของหน้าจอฉันไม่รู้ว่า OP ได้รับ 120 ตั้งแต่แรกยกเว้นว่าเขาหรือเธอทดสอบวิธี px to dp ในขนาดหน้าจอที่แตกต่างกันทั้งหมด
John61590

75

ตามคู่มือการพัฒนา Android:

px = dp * (dpi / 160)

แต่บ่อยครั้งที่คุณต้องการดำเนินการนี้ในทางกลับกันเมื่อคุณได้รับการออกแบบที่ระบุเป็นพิกเซล ดังนั้น:

dp = px / (dpi / 160)

หากคุณใช้อุปกรณ์ 240dpi อัตราส่วนนี้คือ 1.5 (เช่นที่ระบุไว้ก่อนหน้านี้) ดังนั้นหมายความว่าไอคอน 60px เท่ากับ 40dp ในแอปพลิเคชัน


2
Indhu คุณสามารถดูได้ที่นี่ developer.android.com/guide/practices/ … และ developer.android.com/reference/android/util/…
Sachchidanand

7
160 เป็นค่าคงที่คำตอบสำหรับเตียง
25

2
@ user25 คำตอบที่ดีจริง คุณยังไม่ได้อ่านเอกสารใด ๆ บนหน้าจอ Android หรือไม่? 160 เป็นค่าคงที่ทั่วไปทุกที่เมื่อพูดถึงความหนาแน่นของหน้าจอ Android อ้างจากเอกสาร: "หน้าจอความหนาแน่นปานกลาง (mdpi) (~ 160dpi) (นี่คือความหนาแน่นพื้นฐาน)" Come on, man
mykolaj

70

ไม่มีContextวิธีคงที่สง่างาม:

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);
}

24
Resources.getSystem()javadoc กล่าวว่า "ส่งคืนออบเจ็กต์ทรัพยากรที่ใช้ร่วมกันทั่วโลกที่ให้การเข้าถึงทรัพยากรระบบเท่านั้น (ไม่มีทรัพยากรแอปพลิเคชัน) และไม่ได้กำหนดค่าสำหรับหน้าจอปัจจุบัน (ไม่สามารถใช้หน่วยมิติไม่เปลี่ยนแปลงตามการวางแนว ฯลฯ )" สิ่งนี้บอกว่าคุณไม่ควรทำอย่างนี้แม้ว่าจะได้ผลก็ตาม
Austyn Mahoney

ฉันเพิ่งอ่านความคิดเห็นของ @ AustynMahoney และตระหนักว่าคำตอบนี้ไม่ได้ยอดเยี่ยมเท่าที่ฉันเคยคิด แต่เดิมดังนั้นจะไม่ปล่อยให้ฉันยกเลิกการโหวตของฉัน ! โอ๊ะ!
Vicky Chijwani

45

สำหรับ DP to Pixel

สร้างมูลค่าใน dimens.xml

<dimen name="textSize">20dp</dimen>

รับค่านั้นpixelเป็น:

int sizeInPixel = context.getResources().getDimensionPixelSize(R.dimen.textSize);

39

คุณสามารถใช้ formulator ต่อไปนี้เพื่อคำนวณจำนวนพิกเซลที่ถูกต้องจากส่วนข้อมูลที่ระบุใน 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);
}

4
แปลงนี้ DP พิกเซล convertToDpแต่คุณเรียกว่าวิธีการของคุณ
Qwertie

4
+ 0.5f อธิบายได้ที่นี่ -> developer.android.com/guide/practices/… . มันถูกใช้เพื่อปัดเศษให้เป็นจำนวนเต็มที่ใกล้เคียงที่สุด
แบ้

คำตอบที่ถูกต้องเท่านั้น คุณสามารถเพิ่ม source developer.android.com/guide/practices/?hl=th
25

web.archive.org/web/20140808234241/http://developer.android.com/?hl=thสำหรับลิงก์ที่ยังมีเนื้อหาที่เป็นปัญหา
caw

39

สำหรับทุกคนที่ใช้ Kotlin:

val Int.toPx: Int
    get() = (this * Resources.getSystem().displayMetrics.density).toInt()

val Int.toDp: Int
    get() = (this / Resources.getSystem().displayMetrics.density).toInt()

การใช้งาน:

64.toPx
32.toDp

จาก docs สำหรับ Resource.getSystem (): "ส่งคืนออบเจ็กต์ทรัพยากรร่วมส่วนกลางที่ให้การเข้าถึงทรัพยากรระบบเท่านั้น (ไม่มีทรัพยากรแอปพลิเคชัน) และไม่ได้กำหนดค่าสำหรับหน้าจอปัจจุบัน (ไม่สามารถใช้หน่วยมิติไม่เปลี่ยนแปลงตาม ปฐมนิเทศ ฯลฯ ) "
HendraWD

@HendraWD เอกสารอาจทำให้เกิดความสับสนหน่วยข้อมูลที่กล่าวถึงคือระดับแอปพลิเคชันของคุณทำให้ทรัพยากรลดลง displayMetrics ไม่ใช่ทรัพยากรระดับแอปพลิเคชัน เป็นทรัพยากรของระบบและส่งคืนค่าที่ถูกต้อง รหัสนี้ใช้งานได้ดีกับแอพ Prod ทั้งหมดของฉัน ไม่เคยมีปัญหา
Gunhan

33

มีการใช้งานเริ่มต้นใน android SDK: http://developer.android.com/reference/android/util/TypedValue.html

float resultPix = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics())

คุณควรใช้อันนี้ โบนัสจะทำ SP ด้วยเช่นกัน
Mark Renouf

2
resultPixควรเป็นประเภท int int resultPix = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics())
vovahost

27

การใช้ kotlin-extension ทำให้ดีขึ้น

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:

เนื่องจากdisplayMetricsเป็นส่วนหนึ่งของทรัพยากรที่ใช้ร่วมกันทั่วโลกเราจึงสามารถใช้Resources.getSystem()

fun Int.toPx(): Int = (this * Resources.getSystem().displayMetrics.density).toInt()

fun Int.toDp(): Int = (this / Resources.getSystem().displayMetrics.density).toInt()

4
ทำไมคุณถึงเพิ่มมันเป็นส่วนเสริมของ Int ความรับผิดชอบไม่จำเป็นต้องทำอะไรกับประเภท Int
htafoya

19

สิ่งนี้จะให้การแปลง DP เป็นพิกเซล:

public static int dpToPx(int dp)
{
    return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}

สิ่งนี้จะให้พิกเซลการแปลงแก่คุณเป็น dp:

public static int pxToDp(int px)
{
    return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}

19

Kotlin

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);
}

12

อาจเป็นวิธีที่ดีที่สุดถ้าคุณมีมิติภายในค่า / dimen คือรับมิติโดยตรงจากเมธอด getDimension () มันจะคืนค่าขนาดที่แปลงเป็นค่าพิกเซลแล้ว

context.getResources().getDimension(R.dimen.my_dimension)

เพื่ออธิบายสิ่งนี้ให้ดีขึ้น

getDimension(int resourceId) 

จะส่งคืนมิติที่แปลงเป็นพิกเซล AS A FLOAT

getDimensionPixelSize(int resourceId)

จะกลับมาเหมือนเดิม แต่ถูกปัดเศษเป็น int ดังนั้นในฐานะที่เป็น INTEGER

ดูการอ้างอิง Android


9
เพื่อแปลง dp เป็นพิกเซล
public static int dp2px(Resources resource, int dp) {
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,   dp,resource.getDisplayMetrics());
}
ในการแปลงพิกเซลเป็น dp
  public static float px2dp(Resources resource, float px)  {
    return (float) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px,resource.getDisplayMetrics());
}

โดยที่ resource คือ context.getResources ()


8
คำตอบนั้นผิดเพราะคุณไม่ได้แปลงพิกเซลเป็น DP - คุณกำลังแปลงพิกเซลเป็นพิกเซล!
Yaroslav

px2dp ผิด - จะส่งคืนค่าเดียวกันเป็นพิกเซล
natario

8

แบบนี้:

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;
    }
}

ขึ้นอยู่กับบริบทคืนค่าลอยวิธีการคงที่

จาก: https://github.com/Trinea/android-common/blob/master/src/cn/trinea/android/common/util/ScreenUtils.java#L15


8

วิธีการที่หรูหรากว่าโดยใช้ฟังก์ชั่นเสริมของ kotlin

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

การใช้งาน:

println("16 dp in pixel: ${16.dpToPx}")
println("16 px in dp: ${16.pxToDp}")

รักการใช้ส่วนขยายที่นี่ ฉันอ่านฟังก์ชั่นเป็น "แปลงเป็นfunction name" ซึ่งฉันรู้ว่าเป็นไปข้างหลังในกรณีนี้ เพื่อชี้แจงความตั้งใจของแต่ละฟังก์ชั่นชื่อของฟังก์ชั่นสามารถอัปเดตให้อ่าน dpToPx และ pxToDp ตามลำดับ
Maxwell

จาก docs สำหรับ Resource.getSystem (): "ส่งคืนออบเจ็กต์ทรัพยากรร่วมส่วนกลางที่ให้การเข้าถึงทรัพยากรระบบเท่านั้น (ไม่มีทรัพยากรแอปพลิเคชัน) และไม่ได้กำหนดค่าสำหรับหน้าจอปัจจุบัน (ไม่สามารถใช้หน่วยมิติไม่เปลี่ยนแปลงตาม ปฐมนิเทศ ฯลฯ ) "
HendraWD

7
float scaleValue = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scaleValue + 0.5f);

2
นี่ไม่ใช่สิ่งเดียวกับสิ่งที่กล่าวถึงในคำตอบอื่น ๆ ของคำถามนี้หรือไม่?
TZHX

7

ในกรณีที่คุณพัฒนาแอพพลิเคชั่นที่สำคัญเกี่ยวกับประสิทธิภาพโปรดพิจารณาคลาสที่ปรับให้เหมาะสมดังต่อไปนี้:

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;
    }
}

มันทำให้รู้สึกเฉพาะเมื่อคุณทำการแปลงบ่อยมาก ในกรณีของฉันฉันทำ
Pavel

160f คืออะไร ทำไมคุณใช้มันทำไม 160?
dephinera

160 => 160dpi และนี่คือการแปลงการวัดเนื่องจากสูตร
xAqweRx

6

การแปลงพิกเซลเพื่อ DP ใช้TypedValue

ตามเอกสารที่กล่าวมา: คอนเทนเนอร์สำหรับค่าข้อมูลที่พิมพ์แบบไดนามิก

และใช้วิธีApplyDimension :

public static float applyDimension (int unit, float value, DisplayMetrics metrics) 

ซึ่งแปลงค่าของข้อมูลที่ซับซ้อนที่ยังไม่ได้บรรจุซึ่งบรรจุมิติเป็นค่าจุดลอยตัวสุดท้ายดังต่อไปนี้:

Resources resource = getResources();
float dp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 69, resource.getDisplayMetrics());

หวังว่าจะช่วย


6

นี่คือวิธีการทำงานสำหรับฉัน:

DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int  h = displaymetrics.heightPixels;
float  d = displaymetrics.density;
int heightInPixels=(int) (h/d);

คุณสามารถทำเช่นเดียวกันสำหรับความกว้าง



4

คุณควรใช้ dp เช่นเดียวกับที่คุณทำกับพิกเซล นั่นคือทั้งหมดที่พวกเขา; แสดงพิกเซลอิสระ ใช้ตัวเลขเดียวกันกับที่คุณทำบนหน้าจอความหนาแน่นปานกลางและขนาดจะถูกต้องอย่างน่าอัศจรรย์บนหน้าจอความหนาแน่นสูง

อย่างไรก็ตามดูเหมือนสิ่งที่คุณต้องการคือตัวเลือก fill_parent ในการออกแบบเลย์เอาต์ของคุณ ใช้ fill_parent เมื่อคุณต้องการให้มุมมองหรือตัวควบคุมของคุณขยายขนาดที่เหลือทั้งหมดในคอนเทนเนอร์พาเรนต์


ที่จริงแล้วปัญหาของฉันคือแอปพลิเคชันของฉันถูกเข้ารหัสสำหรับหน้าจอที่มีความหนาแน่นสูงและตอนนี้มันจำเป็นต้องแปลงเป็นหน้าจอที่มีความหนาแน่นต่ำ ..
Indhu

แก้ไขพิกเซลของคุณสำหรับหน้าจอความหนาแน่นปานกลาง (คุณสามารถตั้งค่าหน้าจอความหนาแน่นปานกลางในตัวจำลอง) และแทนที่พิกเซลด้วย dp อย่างไรก็ตามแอปพลิเคชันที่ยืดหยุ่นมากขึ้นสามารถทำได้โดยใช้ fill_parent และหลายเลย์เอาต์
Michael Lowman

ในที่สุดฉันไม่มีตัวเลือกนอกจากเปลี่ยน px ทั้งหมดเป็น dp ด้วยตนเอง .. :(
Indhu

1
อย่างน้อยครั้งต่อไปที่คุณจะใช้ dp ก่อนและไม่ต้องเปลี่ยนอะไร :) แม้ว่ามันจะเป็นไปได้ที่จะใช้เลย์เอาต์ที่ไม่ต้องการตำแหน่งที่แน่นอนสำหรับทุกสิ่ง
Michael Lowman

เนื่องจากเป็นแอปแรกของฉัน .. ฉันทำผิดพลาดนี้ ... ฉันจะไม่ทำอีกเลย ... :)
#: 398 Indhu

4

PXและDPแตกต่างกัน แต่คล้ายกัน

DPคือความละเอียดเมื่อคุณคำนึงถึงขนาดทางกายภาพของหน้าจอเท่านั้น เมื่อคุณใช้DPมันจะปรับขนาดเลย์เอาต์ของคุณไปยังหน้าจออื่นที่มีขนาดใกล้เคียงกันซึ่งมีpixelความหนาแน่นต่างกัน

บางครั้งคุณต้องการจริง ๆpixelsและเมื่อคุณจัดการกับส่วนข้อมูลในรหัสคุณมักจะจัดการกับของจริงpixelsเว้นแต่คุณจะแปลง

ดังนั้นบนอุปกรณ์ Android hdpiหน้าจอขนาดปกติ800x480 is 533x320ในDP(ฉันเชื่อว่า) การแปลงDPเข้าpixels /1.5, *1.5การแปลงกลับ นี่เป็นเพียงขนาดหน้าจอเดียวและdpiมันจะเปลี่ยนไปตามการออกแบบ ศิลปินของเราให้ฉันpixelsและฉันก็เปลี่ยนDPเป็น1.5สมการข้างบน


3

ถ้าคุณต้องการค่าจำนวนเต็มการใช้ Math.round () จะปัดเศษทศนิยมเป็นจำนวนเต็มที่ใกล้เคียงที่สุด

public static int pxFromDp(final float dp) {
        return Math.round(dp * Resources.getSystem().getDisplayMetrics().density);
    }


2

Kotlin

   fun spToPx(ctx: Context, sp: Float): Float {
    return sp * ctx.resources.displayMetrics.scaledDensity
}

fun pxToDp(context: Context, px: Float): Float {
    return px / context.resources.displayMetrics.density
}

fun dpToPx(context: Context, dp: Float): Float {
    return dp * context.resources.displayMetrics.density
}

ชวา

   public static float spToPx(Context ctx,float sp){
    return sp * ctx.getResources().getDisplayMetrics().scaledDensity;
}

public static float pxToDp(final Context context, final float px) {
    return px / context.getResources().getDisplayMetrics().density;
}

public static float dpToPx(final Context context, final float dp) {
    return dp * context.getResources().getDisplayMetrics().density;
}

2

คำตอบที่ดีที่สุดมาจากกรอบของ Android: เพียงแค่ใช้ความเท่าเทียมกันนี้ ...

public static int dpToPixels(final DisplayMetrics display_metrics, final float dps) {
    final float scale = display_metrics.density;
    return (int) (dps * scale + 0.5f);
}

(แปลง dp เป็น px)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.