วิธีรับขนาดหน้าจอเป็นพิกเซลใน Android


1842

ฉันสร้างองค์ประกอบที่กำหนดเองบางอย่างและฉันต้องการวางองค์ประกอบเหล่านั้นไปที่มุมขวาบนโดยทางโปรแกรม ( nพิกเซลจากขอบด้านบนและmพิกเซลจากขอบขวา) ดังนั้นฉันต้องได้ความกว้างของหน้าจอและความสูงของหน้าจอจากนั้นตั้งค่าตำแหน่ง:

int px = screenWidth - m;
int py = screenHeight - n;

ฉันจะรับscreenWidthและscreenHeightเข้าร่วมในกิจกรรมหลักได้อย่างไร


ใช้ dp แทน px เพราะมันจะบิดเบือนเลย์เอาต์ของคุณกับอุปกรณ์อื่น ..
Jawad Zeb

อย่าลืมที่จะคูณด้วย getResources (). getDisplayMetrics (). ความหนาแน่นเพื่อแสดงผลการปรับสเกล
jmaculate

นี่เป็นการพิสูจน์ว่าคำตอบที่ได้รับการโหวตมากที่สุดไม่ใช่คำตอบที่ดีที่สุดเสมอ แทนที่จะ getSize และเลิก getWidth / getHeight คำสั่งผสม (ไม่สนใจข้อผิดพลาด) ลอง getMetricsBalaji.K ความคิดเห็นของ Nik ในคำตอบของเขายังอธิบายถึงgetDisplayMetricsการพิจารณาขนาดของระบบ / แถบสถานะ นอกจากนี้คุณอาจจะใช้ความหนาแน่นเป็น jmaculate และ LoungeKatt อธิบายให้มีความแน่นอนคุ้มค่า: DisplayMetrics dm = getResources().getDisplayMetrics(); float fwidth = dm.density * dm.widthPixels;การทดสอบใน Android v2.2 (API 8) และ v4.0 มีผลดีและไม่มีข้อผิดพลาด / คำเตือน
Armfoot

DisplayMetrics displaymetrics = ใหม่ DisplayMetrics (); . getWindowManager () getDefaultDisplay () getMetrics (displaymetrics). int height = displaymetrics.heightPixels; int width = displaymetrics.widthPixels;
Azahar

อีกวิธีหนึ่งที่จะได้รับ DisplayMetrics Resources.getSystem().getDisplayMetrics()นี้: คุณไม่จำเป็นต้องContextได้รับ
Täg

คำตอบ:


3478

หากคุณต้องการขนาดการแสดงผลเป็นพิกเซลคุณสามารถใช้getSize:

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;

หากคุณไม่ได้อยู่ในที่Activityคุณสามารถรับค่าเริ่มต้นDisplayผ่านWINDOW_SERVICE:

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();

หากคุณอยู่ในส่วนและต้องการทราบสิ่งนี้เพียงใช้ Activity.WindowManager (ใน Xamarin.Android) หรือ getActivity (). getWindowManager () (ใน java)

ก่อนgetSizeนำมาใช้ (ในระดับ API 13) คุณสามารถใช้getWidthและgetHeightวิธีที่เลิกใช้แล้ว:

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();  // deprecated
int height = display.getHeight();  // deprecated

สำหรับกรณีการใช้งานที่คุณกำลังอธิบายอย่างไรก็ตามขอบ / ช่องว่างภายในในเค้าโครงดูเหมือนจะเหมาะสมกว่า

อีกวิธีคือ: DisplayMetrics

โครงสร้างที่อธิบายข้อมูลทั่วไปเกี่ยวกับจอแสดงผลเช่นขนาดความหนาแน่นและการปรับขนาดตัวอักษร ในการเข้าถึงสมาชิก DisplayMetrics ให้เริ่มต้นวัตถุเช่นนี้:

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

เราสามารถใช้widthPixelsรับข้อมูลสำหรับ:

"ความกว้างสมบูรณ์ของหน้าจอเป็นพิกเซล"

ตัวอย่าง:

Log.d("ApplicationTagName", "Display width in px is " + metrics.widthPixels);

13
getWidth () หรือ getSize ()? ฉันจะใช้อะไรหากฉันต้องการให้แอปของฉันทำงานบน API <13 และ API> 13
Carol

52
ลอง {display.getSize (ขนาด); width = size.x; height = size.y; } catch (NoSuchMethodError e) {width = display.getWidth (); height = display.getHeight (); }
Arnaud

248
ฉันไม่เห็นสาเหตุที่คุณต้องการใช้try/catchเช็คเช่นนี้? ทำไมไม่ใช้เพียงif (android.os.Build.VERSION.SDK_INT >= 13)โดยไม่มีข้อยกเว้นโยนเลย? ฉันคิดว่าtry/catchแอพพลิเคชั่นตามปกติเป็นวิธีการที่ไม่ดี
Patrik

2
@ A-Live แอปจะหยุดเช่นกัน (แต่ไม่หยุดทำงาน) นักพัฒนาเราต้องตรวจสอบระบบปฏิบัติการเวอร์ชันใหม่ล่วงหน้าและนี่อาจจะเป็นปัญหา ด้วยเหตุผลนี้เราสามารถ / ควรล้อมทุกบรรทัดรหัสสองสามด้วยลอง / จับซึ่งในความคิดของฉันคือการปฏิบัติที่ไม่ดีดังกล่าวแล้ว
Patrik

11
จะทำอย่างไรถ้าคุณต้องการได้ขนาดหน้าจอไม่รวมแถบนำทางและ / หรือแถบการแจ้งเตือน
นักพัฒนา Android

374

วิธีหนึ่งคือ:

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();
int height = display.getHeight();

มันเลิกใช้แล้วและคุณควรลองใช้รหัสต่อไปนี้แทน โค้ดสองบรรทัดแรกให้DisplayMetricsobjecs แก่คุณ วัตถุนี้มีเขตข้อมูลเช่นheightPixels, widthPixels.

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

int height = metrics.heightPixels;
int width = metrics.widthPixels;

14
โปรดทราบว่าการวัด (ความกว้างความสูง) เปลี่ยนแปลงขึ้นอยู่กับการหมุนของอุปกรณ์
Tony Chan

8
ตัวชี้วัดจะส่งคืนขนาดของจอแสดงผล แต่ HoneyComb ขึ้นไปกิจกรรมของคุณจะมีพื้นที่น้อยกว่าสิ่งที่ส่งคืนเนื่องจากแถบระบบ
Guy

3
@ ซื้อมันขึ้นอยู่กับการใช้งานของคุณ คุณสามารถซ่อนแถบสถานะ: requestWindowFeature (Window.FEATURE_NO_TITLE); getWindow (). setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
Hagai L

79
มีอยู่ด้วยวิธีนี้: getContext (). getResources (). getDisplayMetrics (). widthPixels
Nik

ขนาดลอยสุดท้าย = getResources (). getDisplayMetrics (). ความหนาแน่น; int width = (int) (metrics.widthPixels * scale + 0.5f); - คุณต้องคำนึงถึงความหนาแน่นของอุปกรณ์เมื่อทำเช่นนั้น
รถเข็นที่ถูกละทิ้ง

119

อาจไม่ตอบคำถามของคุณ แต่อาจมีประโยชน์ที่จะรู้ (ฉันมองหาตัวเองเมื่อฉันมาถึงคำถามนี้) ว่าถ้าคุณต้องการมิติข้อมูลของ View แต่โค้ดของคุณกำลังถูกเรียกใช้งานเมื่อยังไม่ได้วางเค้าโครง (ตัวอย่างเช่นในonCreate()) คุณสามารถตั้งค่าViewTreeObserver.OnGlobalLayoutListenerด้วยView.getViewTreeObserver().addOnGlobalLayoutListener()และใส่รหัสที่เกี่ยวข้องที่ต้องการมิติของมุมมองที่นั่น การเรียกกลับของผู้ฟังจะถูกเรียกเมื่อเค้าโครงถูกวาง


หรือเพียงแค่เขียน view.post
Lukas Hanacek

view.post ไม่รับประกันว่าจะใช้งานได้ มันเป็นเพียงวิธีแก้ปัญหา
marsbear

@marsbear มันบอกว่าView.post()ไม่รับประกันว่าจะทำงานที่ไหน ฉันอยากรู้อยากเห็นเพราะฉันยังใช้วิธีนี้ในการรับขนาดมุมมองหลังจากเลย์เอาต์และไม่ทราบว่าไม่น่าเชื่อถือ
Tony Chan

@ เทอร์โบฉันพูดว่า: p เราใช้วิธีแก้ปัญหาที่ก่อนหน้านี้และมันกลายเป็นไม่น่าเชื่อถือ วิธีแก้ปัญหานั้นขึ้นอยู่กับข้อสันนิษฐานว่าการวางผังเริ่มต้นจะเสร็จสิ้นภายในเทิร์น UIThread เดียวกับการเริ่มต้น ดังนั้นคุณสามารถกำหนดเวลาให้โค้ดของคุณทำงานก่อนที่ UI ต่อไปจะเปิดผ่านโพสต์ () และใช้ได้ ปรากฎว่าการจัดวางอาจใช้เวลานานกว่าในบางสถานการณ์และมุมมองยังไม่ได้จัดวางเมื่อรหัสที่ลงรายการบัญชีทำงาน สิ่งที่ฉันทำตอนนี้คือเพิ่ม ViewTreeObserver ใน onCreate และลบออกหลังจาก onLayout แรก เริ่มเนื้อหาของคุณในช่วงแรกของการจัดวาง
marsbear

@marsbear มันสำคัญกับสิ่งที่Viewคุณได้รับViewTreeObserverจาก? หรือว่าพวกเขาทั้งหมดแบ่งปันเดียวกันหรือไม่
Tony Chan

109

(คำตอบในปี 2555 อาจล้าสมัย) หากคุณต้องการสนับสนุน Honeycomb ล่วงหน้าคุณจะต้องใส่ความเข้ากันได้ย้อนหลังก่อนหน้า API 13 สิ่งที่ต้องการ:

int measuredWidth = 0;
int measuredHeight = 0;
WindowManager w = getWindowManager();

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    Point size = new Point();
    w.getDefaultDisplay().getSize(size);
    measuredWidth = size.x;
    measuredHeight = size.y;
} else {
    Display d = w.getDefaultDisplay();
    measuredWidth = d.getWidth();
    measuredHeight = d.getHeight();
}

แน่นอนว่าวิธีการที่เลิกใช้แล้วจะถูกนำออกมาจาก SDK ล่าสุด แต่ในขณะที่เรายังคงพึ่งพาผู้ใช้ส่วนใหญ่ที่มี Android 2.1, 2.2 และ 2.3 นี่คือสิ่งที่เราเหลืออยู่


ใช่นี่กลับมาในปี 2012 แล้ว
digiphd

ขออภัยอนุญาตให้ฉันอธิบายสิ่งที่ฉันหมายถึง ไม่น่าเป็นไปได้สูงที่ทุกคนจะสนับสนุน API <14 ตั้งแต่
6/22/2015

69

ฉันได้ลอง "วิธีแก้ปัญหา" ที่เป็นไปได้ทั้งหมดไม่สำเร็จและฉันสังเกตเห็นว่าแอป "Dalvik Explorer" ของ Elliott Hughes แสดงให้เห็นถึงมิติที่ถูกต้องในอุปกรณ์ Android / OS ทุกรุ่น ฉันสิ้นสุดที่ดูโครงการโอเพนซอร์สของเขาที่สามารถพบได้ที่นี่: https://code.google.com/p/enh/

นี่คือรหัสที่เกี่ยวข้องทั้งหมด:

WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
try {
    // used when 17 > SDK_INT >= 14; includes window decorations (statusbar bar/menu bar)
    widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
    heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
try {
    // used when SDK_INT >= 17; includes window decorations (statusbar bar/menu bar)
    Point realSize = new Point();
    Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
    widthPixels = realSize.x;
    heightPixels = realSize.y;
} catch (Exception ignored) {
}

แก้ไข: รุ่นปรับปรุงเล็กน้อย (หลีกเลี่ยงการยิงข้อยกเว้นในรุ่นระบบปฏิบัติการที่ไม่รองรับ):

WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)
try {
    widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
    heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 17)
try {
    Point realSize = new Point();
    Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
    widthPixels = realSize.x;
    heightPixels = realSize.y;
} catch (Exception ignored) {
}

9
นี่เป็นโพสต์เดียวที่นี่ซึ่งคำนึงถึงการตกแต่งหน้าต่าง (แถบสถานะ / แถบเมนู) ทำงานได้ดีสำหรับฉัน
Andy Cochrane

5
ยอดเยี่ยม แต่คุณไม่ควรคาดหวังข้อยกเว้นทางตรรกะในการดำเนินธุรกิจ ข้อยกเว้นการยิง (ถึงแม้จะถูกจับได้) นั้นแย่มากสำหรับประสิทธิภาพ นอกจากนี้คุณกำลังทำงานมากกว่าที่จำเป็นหาก SDK_INT คือ> 13 แต่คุณควรเพิ่ม ifs บางอย่างใน Build.VERSION.SDK_INT
Erik B

3
@Erik B ฉันเห็นด้วย ฉันเพิ่มเวอร์ชันที่ปรับปรุงแล้ว ฉันยังคงออกจากส่วน "ตั้งแต่ SDK 1" ในกรณีที่มีอะไรผิดพลาดในลอง / จับ (ฉันเห็นสิ่งเลวร้ายมากมายใน Android โดยเฉพาะอย่างยิ่งเมื่อคุณคิดว่ามันเป็นไปไม่ได้ที่จะผิดไปดังนั้นฉันต้องการให้ปลอดภัย :)) . อย่างไรก็ตามไม่ควรมีค่าใช้จ่ายมากเกินไปเนื่องจากการคำนวณนี้ควรทำเพียงครั้งเดียว (เช่นค่าอาจถูกเก็บไว้ในแอตทริบิวต์แบบคงที่บางส่วน)
Dragan Marjanović

8
โปรดทราบว่ารหัสนี้ได้รับอนุญาตภายใต้ GPL v3 ซึ่งมีผลกระทบต่อการใช้งานในแอปที่ใช้งานจริง
TalkLittle

GPL และขึ้นอยู่กับการสะท้อนถึงวิธีการโทรซึ่งอาจไม่มีใน Android รุ่นอนาคต Mhhh
Michel

47

วิธีที่ง่ายที่สุด:

 int screenHeight = getResources().getDisplayMetrics().heightPixels;
 int screenWidth = getResources().getDisplayMetrics().widthPixels; 

46

สำหรับการเข้าถึงความสูงของแถบสถานะสำหรับอุปกรณ์ Android เราต้องการวิธีการเขียนโปรแกรม:

โค้ดตัวอย่าง

int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
    result = getResources().getDimensionPixelSize(resId);
}

ตัวแปรresultให้ความสูงเป็นพิกเซล

เพื่อการเข้าถึงที่รวดเร็ว

ป้อนคำอธิบายภาพที่นี่

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับความสูงของTitle bar, Navigation barและContent Viewดูละเมียดละไมบนอุปกรณ์ Android ขนาดหน้าจอ


สิ่งที่ฉันต้องการ! getResources().getDisplayMetrics().heightPixels + resultให้ความสูงเต็มหน้าจอจริง คำตอบของ Dragan Marjanovićก็ใช้ได้เช่นกัน แต่ฉันชอบวิธีที่สั้นกว่าและเรียบง่ายกว่านี้กว่า
มิเชล

วิธีการนี้ล้าสมัยตั้งแต่ Android Marshmallow ความสูงของแถบสถานะสามารถเปลี่ยนจากรุ่นอุปกรณ์หรือ Android OnApplyWindowInsetsListenerการใช้งานที่ดีขึ้น
เฮ็น

32

อันดับแรกรับมุมมอง (เช่นโดยfindViewById()) จากนั้นคุณสามารถใช้getWidth ()บนมุมมองได้


3
นี่คือวิธีที่เอกสารบอกให้คุณทำ ... แต่มันไร้ประโยชน์ถ้าคุณไม่ได้ใช้มุมมอง คุณอาจกำลังใช้อย่างอื่นเช่น mglsurfaceview
gcb

2
สิ่งนี้จะดีกว่าเนื่องจากมุมมองพาเรนต์อาจไม่ใช่ขนาดของจอแสดงผล แต่ตรวจสอบให้แน่ใจว่าสิ่งนี้ทำในจุดที่มุมมองที่คุณสอบถามขนาดได้ถูกจัดเลย์เอาต์แล้วซึ่งโดยปกติจะไม่อยู่ภายใน onCreate () คุณสามารถใช้การโทรกลับที่กำหนดเองจาก onWindowFocusChanged (บูลีน hasFocus) ซึ่งจะถูกเรียกหลังจากวัดมุมมองทั้งหมดและอื่น ๆ เพื่อให้แน่ใจว่าคุณจะไม่ได้รับมิติที่ไม่ถูกต้องสำหรับมุมมองที่คุณสนใจ ...
Dori

27

ฉันมีสองฟังก์ชั่นหนึ่งอันสำหรับส่งบริบทและอีกอันรับความสูงและความกว้างเป็นพิกเซล:

public static int getWidth(Context mContext){
    int width=0;
    WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    if(Build.VERSION.SDK_INT>12){
        Point size = new Point();
        display.getSize(size);
        width = size.x;
    }
    else{
        width = display.getWidth();  // Deprecated
    }
    return width;
}

และ

public static int getHeight(Context mContext){
    int height=0;
    WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    if(Build.VERSION.SDK_INT>12){
        Point size = new Point();
        display.getSize(size);
        height = size.y;
    }
    else{
        height = display.getHeight();  // Deprecated
    }
    return height;
}

คุณต้องเพิ่ม@SuppressLint("NewApi")ลายเซ็นของฟังก์ชันเพื่อให้สามารถรวบรวมได้
Adil Malik

ฉันคิดว่ามันจะดีกว่าถ้าได้ความสูงและความกว้างในคราวเดียวแทนที่จะใช้การเรียก API ที่แยกต่างหากเพราะไม่เช่นนั้นอาจไม่ซิงค์กัน สิ่งนี้อาจเกิดขึ้นได้หากการวางแนวหน้าจอเปลี่ยนไปในขณะที่รหัสของคุณกำลังทำงาน
Sam

17

สำหรับการปรับขนาดแบบไดนามิกโดยใช้ XML จะมีแอตทริบิวต์ชื่อ "android: layout_weight"

ตัวอย่างด้านล่างซึ่งแก้ไขจากการตอบสนองของซินซิคในเธรดนี้แสดงปุ่มที่ใช้เวลาถึง 75% ของหน้าจอ (น้ำหนัก = 0.25) และมุมมองข้อความที่ใช้พื้นที่ที่เหลืออีก 25% ของหน้าจอ (น้ำหนัก = .75)

<LinearLayout android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight=".25"
        android:text="somebutton">

    <TextView android:layout_width="fill_parent"
        android:layout_height="Wrap_content"
        android:layout_weight=".75">
</LinearLayout>

17

นี่คือรหัสที่ฉันใช้สำหรับงาน:

// `activity` is an instance of Activity class.
Display display = activity.getWindowManager().getDefaultDisplay();
Point screen = new Point();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    display.getSize(screen);
} else {            
    screen.x = display.getWidth();
    screen.y = display.getHeight();
}

ดูเหมือนจะสะอาดเพียงพอและยังดูแลการคัดค้าน


17

นี่ไม่ใช่ทางออกที่ดีกว่าใช่ไหม DisplayMetricsมาพร้อมกับทุกสิ่งที่คุณต้องการและทำงานได้จาก API 1

public void getScreenInfo(){
    DisplayMetrics metrics = new DisplayMetrics();
    getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);

    heightPixels = metrics.heightPixels;
    widthPixels = metrics.widthPixels;
    density = metrics.density;
    densityDpi = metrics.densityDpi;
}

คุณสามารถรับการแสดงผลจริง (รวมถึงตัวตกแต่งหน้าจอเช่นแถบสถานะหรือแถบการนำทางซอฟต์แวร์) โดยใช้getRealMetricsแต่ใช้งานได้กับ 17+ เท่านั้น

ฉันพลาดอะไรไปรึเปล่า?


1
มันไม่ได้ลบพื้นที่สำหรับการควบคุมบนหน้าจอ (เช่นบนแท็บเล็ตหรืออุปกรณ์ Nexus) นอกจากนี้ฉันยังได้รับค่าที่แตกต่าง (750 vs 800) บนแท็บเล็ต 10 "ของฉันขึ้นอยู่กับว่ากิจกรรมนั้นใช้งานได้หรือไม่เมื่อคำนวณเสร็จ แต่สำหรับจุดประสงค์ของฉันมันดีกว่านี้มากขอบคุณ
Steven L

15

เพียงเพิ่มคำตอบของ Francesco ผู้สังเกตการณ์คนอื่น ๆ ที่มีความฉลาดมากขึ้นหากคุณต้องการค้นหาตำแหน่งในหน้าต่างหรือตำแหน่งในหน้าจอคือ ViewTreeObserver.OnPreDrawListener ()

นอกจากนี้ยังสามารถใช้เพื่อค้นหาคุณลักษณะอื่น ๆ ของมุมมองที่ส่วนใหญ่ไม่ทราบเวลา onCreate () เช่นตำแหน่งที่เลื่อนตำแหน่งที่ปรับขนาด


15

ใช้รหัสต่อไปนี้ในกิจกรรม

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int wwidth = metrics.widthPixels;

15

ค้นหาความกว้างและความสูงของหน้าจอ:

width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();

เมื่อใช้สิ่งนี้เราจะได้ SDK 13 ขึ้นไป

// New width and height
int version = android.os.Build.VERSION.SDK_INT;
Log.i("", " name == "+ version);
Display display = getWindowManager().getDefaultDisplay();
int width;
if (version >= 13) {
    Point size = new Point();
    display.getSize(size);
    width = size.x;
    Log.i("width", "if =>" +width);
}
else {
    width = display.getWidth();
    Log.i("width", "else =>" +width);
}



12

ต้องบอกว่าถ้าคุณไม่ได้อยู่ในActivityแต่ในView(หรือมีตัวแปรViewประเภทในขอบเขตของคุณ) ไม่จำเป็นต้องใช้WINDOW_SERVICEมีไม่จำเป็นต้องใช้ จากนั้นคุณสามารถใช้อย่างน้อยสองวิธี

ครั้งแรก:

DisplayMetrics dm = yourView.getContext().getResources().getDisplayMetrics();

ประการที่สอง:

DisplayMetrics dm = new DisplayMetrics();
yourView.getDisplay().getMetrics(dm);

วิธีการทั้งหมดที่เราเรียกที่นี่ไม่ได้คัดค้าน


12
public class AndroidScreenActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        String str_ScreenSize = "The Android Screen is: "
                                   + dm.widthPixels
                                   + " x "
                                   + dm.heightPixels;

        TextView mScreenSize = (TextView) findViewById(R.id.strScreenSize);
        mScreenSize.setText(str_ScreenSize);
    }
}

11

สำหรับการรับขนาดหน้าจอใช้เมทริกซ์การแสดงผล

DisplayMetrics displayMetrics = new DisplayMetrics();
if (context != null) 
      WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
      Display defaultDisplay = windowManager.getDefaultDisplay();
      defaultDisplay.getRealMetrics(displayMetrics);
    }

รับส่วนสูงและความกว้างเป็นพิกเซล

int width  =displayMetrics.widthPixels;
int height =displayMetrics.heightPixels;

9

นี่ไม่ใช่คำตอบสำหรับ OP เนื่องจากเขาต้องการขนาดการแสดงผลเป็นพิกเซลจริง ฉันต้องการขนาดใน "อุปกรณ์อิสระพิกเซล" และรวบรวมคำตอบจากที่นี่https://stackoverflow.com/a/17880012/253938และที่นี่https://stackoverflow.com/a/6656774/253938ฉันมา ด้วยสิ่งนี้:

    DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
    int dpHeight = (int)(displayMetrics.heightPixels / displayMetrics.density + 0.5);
    int dpWidth = (int)(displayMetrics.widthPixels / displayMetrics.density + 0.5);

9

คุณสามารถรับขนาดความสูงโดยใช้:

getResources().getDisplayMetrics().heightPixels;

และขนาดความกว้างโดยใช้

getResources().getDisplayMetrics().widthPixels; 

8

มีวิธีที่ไม่คัดค้านโดยใช้ DisplayMetrics (API 1) ที่หลีกเลี่ยงการพยายาม / จับความยุ่งเหยิง:

 // initialize the DisplayMetrics object
 DisplayMetrics deviceDisplayMetrics = new DisplayMetrics();

 // populate the DisplayMetrics object with the display characteristics
 getWindowManager().getDefaultDisplay().getMetrics(deviceDisplayMetrics);

 // get the width and height
 screenWidth = deviceDisplayMetrics.widthPixels;
 screenHeight = deviceDisplayMetrics.heightPixels;

8

ฉันจะตัดรหัส getSize ดังนี้:

@SuppressLint("NewApi")
public static Point getScreenSize(Activity a) {
    Point size = new Point();
    Display d = a.getWindowManager().getDefaultDisplay();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        d.getSize(size);
    } else {
        size.x = d.getWidth();
        size.y = d.getHeight();
    }
    return size;
}

สิ่งนี้ขัดข้องบนอีมูเลเตอร์ที่รัน Android 4.0 (API 14)
jww

6

สำหรับผู้ที่กำลังค้นหาขนาดหน้าจอที่ใช้งานได้โดยไม่มีStatus BarและAction Bar (ต้องขอบคุณคำตอบของ Swapnil):

DisplayMetrics dm = getResources().getDisplayMetrics();
float screen_w = dm.widthPixels;
float screen_h = dm.heightPixels;

int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
    screen_h -= getResources().getDimensionPixelSize(resId);
}

TypedValue typedValue = new TypedValue();
if(getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)){
    screen_h -= getResources().getDimensionPixelSize(typedValue.resourceId);
}

6

ก่อนโหลดไฟล์ XML แล้วเขียนรหัสนี้:

setContentView(R.layout.main);      
Display display = getWindowManager().getDefaultDisplay();
final int width = (display.getWidth());
final int height = (display.getHeight());

แสดงความกว้างและความสูงตามความละเอียดหน้าจอของคุณ


6

ทำตามวิธีการด้านล่าง:

public static int getWidthScreen(Context context) {
    return getDisplayMetrics(context).widthPixels;
}

public static int getHeightScreen(Context context) {
    return getDisplayMetrics(context).heightPixels;
}

private static DisplayMetrics getDisplayMetrics(Context context) {
    DisplayMetrics displayMetrics = new DisplayMetrics();
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    wm.getDefaultDisplay().getMetrics(displayMetrics);
    return displayMetrics;
}

6

Kotlin

fun getScreenHeight(activity: Activity): Int {
    val metrics = DisplayMetrics()
    activity.windowManager.defaultDisplay.getMetrics(metrics)
    return metrics.heightPixels
}

fun getScreenWidth(activity: Activity): Int {
    val metrics = DisplayMetrics()
    activity.windowManager.defaultDisplay.getMetrics(metrics)
    return metrics.widthPixels
}

5

มีบางครั้งที่คุณจำเป็นต้องรู้ขนาดที่แม่นยำของพื้นที่ที่มีอยู่สำหรับรูปแบบเมื่ออยู่ในกิจกรรมของ onCreate หลังจากความคิดบางอย่างฉันทำมันด้วยวิธีนี้

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startActivityForResult(new Intent(this, Measure.class), 1);
        // Return without setting the layout, that will be done in onActivityResult.
    }

    @Override
    protected void onActivityResult (int requestCode, int resultCode, Intent data) {
        // Probably can never happen, but just in case.
        if (resultCode == RESULT_CANCELED) {
            finish();
            return;
        }
        int width = data.getIntExtra("Width", -1);
        // Width is now set to the precise available width, and a layout can now be created.            ...
    }
}

public final class Measure extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
       // Create a LinearLayout with a MeasureFrameLayout in it.
        // Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way.
        LinearLayout linearLayout = new LinearLayout(this);
        LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this);
        measureFrameLayout.setLayoutParams(matchParent);
        linearLayout.addView(measureFrameLayout);
        this.addContentView(linearLayout, matchParent);
        // measureFrameLayout will now request this second activity to finish, sending back the width.
    }

    class MeasureFrameLayout extends FrameLayout {
        boolean finished = false;
        public MeasureFrameLayout(Context context) {
            super(context);
        }

        @SuppressLint("DrawAllocation")
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            if (finished) {
                return;
            }
            finished = true;
            // Send the width back as the result.
            Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec));
            Measure.this.setResult(Activity.RESULT_OK, data);
            // Tell this activity to finish, so the result is passed back.
            Measure.this.finish();
        }
    }
}

หากด้วยเหตุผลบางอย่างที่คุณไม่ต้องการเพิ่มกิจกรรมอื่นในรายการ Android คุณสามารถทำได้ด้วยวิธีนี้:

public class MainActivity extends Activity {
    static Activity measuringActivity;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        Bundle extras = getIntent().getExtras();
        if (extras == null) {
            extras = new Bundle();
        }
        int width = extras.getInt("Width", -2);
        if (width == -2) {
            // First time in, just start another copy of this activity.
            extras.putInt("Width", -1);
            startActivityForResult(new Intent(this, MainActivity.class).putExtras(extras), 1);
            // Return without setting the layout, that will be done in onActivityResult.
            return;
        }
        if (width == -1) {
            // Second time in, here is where the measurement takes place.
            // Create a LinearLayout with a MeasureFrameLayout in it.
            // Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way.
            LinearLayout linearLayout = new LinearLayout(measuringActivity = this);
            LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this);
            measureFrameLayout.setLayoutParams(matchParent);
            linearLayout.addView(measureFrameLayout);
            this.addContentView(linearLayout, matchParent);
            // measureFrameLayout will now request this second activity to finish, sending back the width.
        }
    }

    @Override
    protected void onActivityResult (int requestCode, int resultCode, Intent data) {
        // Probably can never happen, but just in case.
        if (resultCode == RESULT_CANCELED) {
            finish();
            return;
        }
        int width = data.getIntExtra("Width", -3);
        // Width is now set to the precise available width, and a layout can now be created. 
        ...
    }

class MeasureFrameLayout extends FrameLayout {
    boolean finished = false;
    public MeasureFrameLayout(Context context) {
        super(context);
    }

    @SuppressLint("DrawAllocation")
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (finished) {
            return;
        }
        finished = true;
        // Send the width back as the result.
        Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec));
        MainActivity.measuringActivity.setResult(Activity.RESULT_OK, data);
        // Tell the (second) activity to finish.
        MainActivity.measuringActivity.finish();
    }
}    

เห็นได้ชัดว่าคุณสามารถส่งคืนความสูงในชุดข้อมูลได้เช่นกัน
Steve Waring

5

หากคุณไม่ต้องการโอเวอร์เฮดของ WindowManagers, แต้มหรือดิสเพลย์คุณสามารถคว้าคุณสมบัติความสูงและความกว้างของรายการมุมมองสูงสุดใน XML ของคุณโดยกำหนดความสูงและความกว้างเป็น match_parent (สิ่งนี้เป็นจริงตราบใดที่เลย์เอาต์ของคุณเต็มหน้าจอ)

ตัวอย่างเช่นหาก XML ของคุณเริ่มต้นด้วยสิ่งนี้:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/entireLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

จากนั้นfindViewById(R.id.entireLayout).getWidth()จะกลับความกว้างของหน้าจอและfindViewById(R.id.entireLayout).getHeight()จะกลับความสูงของหน้าจอ

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