จะกำหนดความกว้างของหน้าจอในรูปของ dp หรือ dip at runtime ใน Android ได้อย่างไร?


194

ฉันต้องการโค้ดเลย์เอาต์ของวิดเจ็ต Android โดยใช้ dip / dp (ในไฟล์ java) ที่รันไทม์ถ้าฉันรหัส

int pixel=this.getWindowManager().getDefaultDisplay().getWidth();

ส่งคืนความกว้างของหน้าจอเป็นพิกเซล (px) ในการแปลงเป็น dp ฉันได้โค้ด:

int dp =pixel/(int)getResources().getDisplayMetrics().density ;

มันดูเหมือนจะไม่ได้คำตอบที่ถูกต้อง ฉันสร้างอีมูเลเตอร์ของ WVGA800 ซึ่งมีความละเอียดหน้าจอที่ 480 โดย 800 เมื่อรันอีมูเลเตอร์และให้โค้ดพิมพ์ค่าพิกเซลและ dp มันมาที่ 320 ทั้งคู่ อีมูเลเตอร์นี้คือ 240 dpi โดยค่าตัวคูณจะเท่ากับ 0.75

คำตอบ:


378

ลองสิ่งนี้

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics ();
display.getMetrics(outMetrics);

float density  = getResources().getDisplayMetrics().density;
float dpHeight = outMetrics.heightPixels / density;
float dpWidth  = outMetrics.widthPixels / density;

หรือ

ขอบคุณ @ TomášHubálek

DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();    
float dpHeight = displayMetrics.heightPixels / displayMetrics.density;
float dpWidth = displayMetrics.widthPixels / displayMetrics.density;

91
เหตุใดจึงจำเป็นต้องเรียก WindowManager แล้วรหัสนี้ล่ะ? DisplayMetrics displayMetrics = resources.getDisplayMetrics (); float screenWidthDp = displayMetrics.widthPixels / displayMetrics.density;
TomášHubálek

2
สิ่งนี้ไม่ได้ผลสำหรับฉันโดยใช้หน้าจอความหนาแน่นสูงมาก ราวกับว่ามันเป็นเพียงส่วนเล็ก ๆ ของหน้าจอ วิธีนี้ใช้ได้ผลกับฉัน: stackoverflow.com/a/18712361/956975 Display display = getWindowManager (). getDefaultDisplay (); ขนาดพอยต์ = จุดใหม่ (); display.getSize (ขนาด); int width = size.x; int height = size.y;
marienke

1
@dsdsdsdsd: บริบทเป็นตัวอย่างของคลาสบริบท สิ่งที่สะดุดตาที่สุดคือกิจกรรมเป็นบริบทย่อยของคลาส (ดังนั้นให้ใช้สิ่งนี้ในกิจกรรมและ getActivity () เป็นส่วน ๆ ) แอปพลิเคชันและบริการเป็นคลาสย่อยของบริบท
François POYER

112

ฉันสะดุดคำถามนี้จาก Google และต่อมาฉันพบวิธีแก้ปัญหาที่ใช้ได้ง่ายสำหรับ API> = 13

สำหรับการอ้างอิงในอนาคต:

Configuration configuration = yourActivity.getResources().getConfiguration();
int screenWidthDp = configuration.screenWidthDp; //The current width of the available screen space, in dp units, corresponding to screen width resource qualifier.
int smallestScreenWidthDp = configuration.smallestScreenWidthDp; //The smallest screen size an application will see in normal operation, corresponding to smallest screen width resource qualifier.

ดูการอ้างอิงคลาสคอนฟิกูเรชัน

แก้ไข: ตามที่ระบุไว้โดย Nick Baicoianu สิ่งนี้จะส่งกลับความกว้าง / ความสูงที่ใช้งานได้ของหน้าจอ (ซึ่งควรเป็นสิ่งที่น่าสนใจที่สุดในการใช้งานส่วนใหญ่) หากคุณต้องการขนาดจอแสดงผลที่แท้จริงติดกับคำตอบด้านบน


23
ความแตกต่างที่สำคัญอย่างหนึ่งระหว่างการใช้หน้าจอการตั้งค่าของ WidthDp / screenHeightDp เทียบกับ DisplayMetrics widthPixels / heightPixels คือการตั้งค่าจะส่งคืนมิติการแสดงผลที่ใช้งานได้ (ลบด้วยแถบสถานะเป็นต้น) ในขณะที่ DisplayMetrics
Nick Baicoianu

นี้เป็นเพียงสำหรับ API ระดับ 13 ขึ้นไป
Ono

หากต้องการเพิ่มความคิดเห็นของ @ NickBaicoianu ทั้งเมธอด getConfiguration () และ getDisplayMetrics () จะทำงานในโหมดหลายหน้าต่าง เช่นขนาดสะท้อนให้เห็นถึงของหน้าต่างไม่ใช่หน้าจอ
nmw

7

คุณไม่มีค่าความหนาแน่นเริ่มต้นที่ 160

    2 px = 3 dip if dpi == 80(ldpi), 320x240 screen
    1 px = 1 dip if dpi == 160(mdpi), 480x320 screen
    3 px = 2 dip if dpi == 240(hdpi), 840x480 screen

กล่าวอีกนัยหนึ่งถ้าคุณออกแบบเลย์เอาต์ที่มีความกว้างเท่ากับ 160dip ในโหมดแนวตั้งมันจะเป็นครึ่งหนึ่งของหน้าจอในอุปกรณ์ ldpi / mdpi / hdpi ทั้งหมด (ยกเว้นแท็บเล็ตฉันคิดว่า)


สิ่งที่คุณตอบเป็นเหตุผลเชิงตรรกะที่อยู่เบื้องหลังคำถามของฉัน ฉันเข้าใจสิ่งนี้ ฉันควรเขียนโค้ดนี้ในจาวาอย่างไรเพื่อให้รันไทม์ไม่ว่าความละเอียดหน้าจอคืออะไร
Khushboo

หวังว่าฉันจะทำให้ถูกต้องในครั้งนี้ :) ใช้DisplayMetrics outMetrics = null; getWindowManager().getDefaultDisplay().getMetrics(outMetrics);ภายในกิจกรรม จากนั้นoutMetrics.densityจะให้ตัวคูณสเกลของอุปกรณ์ปัจจุบันตามที่ระบุไว้ในเอกสาร
Mykhailo Gaidai

6

วิธีการเกี่ยวกับการใช้สิ่งนี้แทน?

final DisplayMetrics displayMetrics=getResources().getDisplayMetrics();
final float screenWidthInDp=displayMetrics.widthPixels/displayMetrics.density;
final float screenHeightInDp=displayMetrics.heightPixels/displayMetrics.density;

6
DisplayMetrics displayMetrics = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

int width_px = Resources.getSystem().getDisplayMetrics().widthPixels;

int height_px =Resources.getSystem().getDisplayMetrics().heightPixels;

int pixeldpi = Resources.getSystem().getDisplayMetrics().densityDpi;


int width_dp = (width_px/pixeldpi)*160;
int height_dp = (height_px/pixeldpi)*160;

8
พิจารณาให้บางคำอธิบาย
bigbounty

5

คำตอบใน kotlin:

  context?.let {
        val displayMetrics = it.resources.displayMetrics
        val dpHeight = displayMetrics.heightPixels / displayMetrics.density
        val dpWidth = displayMetrics.widthPixels / displayMetrics.density
    }

4

ประยุกต์สำหรับ Kotlin:

val widthDp = resources.displayMetrics.run { widthPixels / density }
val heightDp = resources.displayMetrics.run { heightPixels / density }

2

รับความกว้างและความสูงของหน้าจอในแง่ของ DP ด้วยการตกแต่งที่ดี:

ขั้นตอนที่ 1: สร้างอินเตอร์เฟส

public interface ScreenInterface {

   float getWidth();

   float getHeight();

}

ขั้นตอนที่ 2: สร้างคลาส implementer

public class Screen implements ScreenInterface {
    private Activity activity;

    public Screen(Activity activity) {
        this.activity = activity;
    }

    private DisplayMetrics getScreenDimension(Activity activity) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        return displayMetrics;
    }

    private float getScreenDensity(Activity activity) {
        return activity.getResources().getDisplayMetrics().density;
    }

    @Override
    public float getWidth() {
        DisplayMetrics displayMetrics = getScreenDimension(activity);
        return displayMetrics.widthPixels / getScreenDensity(activity);
    }

    @Override
    public float getHeight() {
        DisplayMetrics displayMetrics = getScreenDimension(activity);
        return displayMetrics.heightPixels / getScreenDensity(activity);
    }
} 

ขั้นตอนที่ 3: รับความกว้างและความสูงในกิจกรรม:

Screen screen = new Screen(this); // Setting Screen
screen.getWidth();
screen.getHeight();

สิ่งนี้ส่งคืนความสูงและความกว้างเป็นพิกเซลหรือ dp หรือไม่
Taslim Oseni

ในฐานะที่เป็น. ความหนาแน่นนั่นคือเหตุผลที่มันให้คุณใน DP
Ali Azaz Alam

ฉันไม่คิดว่าเป็นความคิดที่ดีที่จะเพิ่มรหัสลงในแอปของคุณเพื่อแก้ปัญหาอย่างง่าย
Ruslan Berozov

ท่านมันขึ้นอยู่กับคุณไม่ว่าจะใช้คลาสหรือรหัสโดยตรง จากคลาสที่กำหนดไว้คุณสามารถแยกรหัสเพื่อนำไปใช้โดยตรงได้อย่างง่ายดาย
Ali Azaz Alam

0

หากคุณต้องการทราบเกี่ยวกับความกว้างของหน้าจอคุณสามารถค้นหา "ความกว้างหน้าจอที่เล็กที่สุด" ในตัวเลือกนักพัฒนาของคุณ คุณสามารถแก้ไขได้



-5

ปัญหาของคุณคือการหล่อลอยให้เป็น int สูญเสียความแม่นยำ คุณควรคูณด้วยปัจจัยและไม่หาร

ทำเช่นนี้:

int dp = (int)(pixel*getResources().getDisplayMetrics().density);

3
คำตอบนี้ไม่ถูกต้อง จากdeveloper.android.com/guide/practices/… , Pixel = Dp * ความหนาแน่น
Vance-Turner
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.