Câu hỏi Nhận kích thước màn hình bằng pixel


Tôi đã tạo một số yếu tố tùy chỉnh và tôi muốn đặt chúng ở góc trên bên phảin pixel từ cạnh trên cùng và m pixel từ cạnh phải). Vì vậy, tôi cần phải có chiều rộng màn hình và chiều cao màn hình và sau đó thiết lập vị trí:

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

Làm sao tôi có thể lấy screenWidth và screenHeight trong Hoạt động chính?


1672
2018-06-19 08:25


gốc


Sử dụng dp thay vì px. bởi vì nó sẽ bóp méo bố cục của bạn với các thiết bị khác .. - Nepster
Đừng quên nhân với mật độ getResources (). GetDisplayMetrics (). Để tính tỷ lệ hiển thị - jmaculate
Điều này chứng tỏ câu trả lời được bỏ phiếu nhiều nhất không phải lúc nào cũng tốt nhất (và rất nhiều người lặp lại câu trả lời cho đại diện). Thay vì getSize và không dùng combo getWidth / getHeight (bỏ qua lỗi), hãy thử Balaji.K's getMetrics. Bình luận của Nik trong câu trả lời của anh ấy thậm chí còn giải thích getDisplayMetrics để xem xét kích thước thanh hệ thống / trạng thái. Ngoài ra bạn có thể sử dụng tỉ trọng như jmaculate và LoungeKatt giải thích để có CHÍNH XÁC giá trị:DisplayMetrics dm = getResources().getDisplayMetrics(); float fwidth = dm.density * dm.widthPixels; Thử nghiệm trong Android v2.2 (API 8) và v4.0 với kết quả tốt và không có lỗi / cảnh báo. - Armfoot
DisplayMetrics displaymetrics = new DisplayMetrics (); getWindowManager () getMetrics (displaymetrics); int height = displaymetrics.heightPixels; int width = displaymetrics.widthPixels; - Azahar


Các câu trả lời:


Nếu bạn muốn kích thước hiển thị bằng pixel, bạn có thể sử dụng getSize:

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

Nếu bạn không ở trong một Activity bạn có thể nhận được mặc định Display thông qua WINDOW_SERVICE:

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

Trước getSize đã được giới thiệu (trong API cấp 13), bạn có thể sử dụng getWidth và getHeight các phương pháp hiện không được chấp nhận:

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

Tuy nhiên, đối với trường hợp sử dụng bạn mô tả, một lề / đệm trong bố cục có vẻ thích hợp hơn.

Một cách khác là: DisplayMetrics

Cấu trúc mô tả thông tin chung về màn hình, chẳng hạn như kích thước, mật độ và tỷ lệ phông chữ. Để truy cập các thành viên DisplayMetrics, khởi tạo một đối tượng như sau:

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

Chúng ta có thể sử dụng widthPixels để nhận thông tin về:

"Độ rộng tuyệt đối của màn hình tính bằng pixel".

Thí dụ:

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

3328
2018-06-19 08:41



developer.android.com/reference/android/view/Display.html - gcb
getWidth () hoặc getSize ()? Tôi sẽ sử dụng những gì nếu tôi cần ứng dụng của mình chạy trên API <13 cũng như API> 13? - Carol
thử {display.getSize (kích thước); width = size.x; height = size.y; } catch (NoSuchMethodError e) {width = display.getWidth (); height = display.getHeight (); } - Arnaud
Tôi không hiểu tại sao bạn muốn sử dụng try/catch để kiểm tra như vậy? Tại sao không chỉ đơn giản là sử dụng if (android.os.Build.VERSION.SDK_INT >= 13) mà không có bất kỳ ngoại lệ ném nào cả? Tôi nghĩ về try/catch trong một luồng ứng dụng thông thường là thực hành không tốt. - CipherCom
nếu bạn muốn có kích thước màn hình không bao gồm thanh điều hướng và / hoặc thanh thông báo - android developer


Một cách là:

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

Nó không được chấp nhận và bạn nên thử mã sau đây để thay thế. Hai dòng mã đầu tiên cung cấp cho bạn objecs DisplayMetrics. Đối tượng này chứa các trường như heightPixels, widthPixels.

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

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

350
2018-01-31 02:01



Lưu ý rằng các chỉ số (chiều rộng, chiều cao) thay đổi tùy thuộc vào vòng xoay của thiết bị. - Tony Chan
Số liệu sẽ trả về kích thước của màn hình, nhưng HoneyComb trở lên, hoạt động của bạn sẽ có ít không gian hơn so với số được trả về do thanh hệ thống. - Guy
@Guy nó phụ thuộc vào việc thực hiện của bạn. Bạn có thể ẩn thanh trạng thái: requestWindowFeature (Window.FEATURE_NO_TITLE); getWindow (). setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); - Hagai L
Cũng tồn tại theo cách này: getContext (). GetResources (). GetDisplayMetrics (). WidthPixels - Nik
final float scale = getResources (). getDisplayMetrics (). mật độ; int width = (int) (metric.widthPixels * scale + 0.5f); - Bạn phải tính toán mật độ thiết bị khi thực hiện theo cách đó. - Abandoned Cart


Nó có thể không trả lời câu hỏi của bạn, nhưng nó có thể hữu ích để biết (tôi đang tìm kiếm nó khi tôi đến câu hỏi này) rằng nếu bạn cần kích thước của View nhưng mã của bạn đang được thực hiện khi bố cục của nó chưa được đặt ra (ví dụ: onCreate() ) bạn có thể thiết lập ViewTreeObserver.OnGlobalLayoutListener với View.getViewTreeObserver().addOnGlobalLayoutListener() và đặt mã có liên quan cần kích thước của chế độ xem tại đó. Cuộc gọi lại của người nghe sẽ được gọi khi bố cục sẽ được bố trí.


111
2018-04-06 21:23



hoặc chỉ viết view.post - Lukas Hanacek
một ý chính để thực hiện nhanh :) gist.github.com/doridori/9208247 - Dori
view.post không được bảo đảm để hoạt động. Nó chỉ là một cách giải quyết. - marsbear
@ marsbear nó nói ở đâu View.post() không được bảo đảm để làm việc? Tôi tò mò vì tôi cũng dựa vào phương pháp này để có được kích thước của View sau khi bố trí và không biết nó không đáng tin cậy. - Tony Chan
@Turbo Tôi nói rằng: p Chúng tôi đã sử dụng cách giải quyết đó trước đây và hóa ra là không đáng tin cậy. Cách giải quyết đó dựa trên giả định, rằng việc bố trí ban đầu được thực hiện trong cùng một lượt UIThread như khởi tạo. Do đó, bạn có thể lên lịch cho mã của mình chạy trước giao diện người dùng tiếp theo qua bài đăng () và sẽ ổn. Nó bật ra rằng việc bố trí có thể mất nhiều thời gian hơn trong những trường hợp nhất định và xem vẫn không được bố trí khi mã được đăng chạy. Những gì tôi làm bây giờ là thêm ViewTreeObserver vào onCreate và loại bỏ nó sau onLayout đầu tiên. Bắt đầu công cụ của bạn trong lần đầu tiên onLayout. - marsbear


(Câu trả lời năm 2012, có thể lỗi thời) Nếu bạn muốn hỗ trợ trước Honeycomb, bạn sẽ cần phải đưa vào khả năng tương thích ngược trước API 13. Một cái gì đó như:

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

Tất nhiên, các phương pháp không được sử dụng cuối cùng sẽ được đưa ra khỏi các SDK gần đây nhất, nhưng trong khi chúng tôi vẫn dựa vào hầu hết người dùng của chúng tôi có Android 2.1, 2.2 và 2.3, đây là những gì chúng tôi còn lại.


103
2017-07-24 03:14



Vâng, điều này đã trở lại vào năm 2012. - digiphd
xin lỗi, cho phép tôi làm rõ ý tôi là gì. Rất khó có ai hỗ trợ API <14 kể từ ngày 22/6/2015 - sudocoder


Tôi đã thử tất cả "giải pháp" có thể không thành công và tôi nhận thấy rằng ứng dụng "Dalvik Explorer" của Elliott Hughes luôn hiển thị đúng kích thước trên bất kỳ phiên bản thiết bị / HĐH Android nào. Tôi đã xem xét dự án nguồn mở của anh ấy có thể tìm thấy ở đây: https://code.google.com/p/enh/

Đây là tất cả các mã có liên quan:

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

EDIT: phiên bản cải tiến một chút (tránh bắn ngoại lệ trên phiên bản hệ điều hành không được hỗ trợ):

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

62
2018-03-29 08:15



Đây là bài duy nhất ở đây có tính đến các trang trí cửa sổ (thanh trạng thái / thanh trình đơn). làm việc tuyệt vời cho tôi. - Andy Cochrane
Tuyệt vời, tuy nhiên bạn không bao giờ nên dự kiến ​​trường hợp ngoại lệ lửa kinh doanh. Bắn ngoại lệ (ngay cả khi bị bắt) là khủng khiếp cho hiệu suất. Ngoài ra, bạn đang làm nhiều việc hơn cần thiết nếu SDK_INT là> 13. Thay vào đó, bạn chỉ nên thêm một số ifs trên Build.VERSION.SDK_INT. - Erik B
@ Erik B, tôi đồng ý. Tôi đã thêm phiên bản cải tiến. Tôi vẫn để lại phần "kể từ SDK 1" trong trường hợp có sự cố trong try / catch (tôi đã thấy nhiều điều xấu trong Android đặc biệt là khi bạn nghĩ rằng nó không thể làm điều gì sai vì vậy tôi muốn giữ nó an toàn :)) . Dù sao thì không nên quá chi phí mouch vì tính toán này chỉ nên được thực hiện một lần (ví dụ: giá trị có thể được giữ trong một số thuộc tính tĩnh). - Dragan Marjanović
Lưu ý rằng mã này được cấp phép theo GPL v3 có tác động đến việc sử dụng trong các ứng dụng sản xuất. - TalkLittle
GPL và tùy thuộc vào sự phản ánh các phương thức gọi có thể không có trong các phiên bản Android trong tương lai. Mhhh - Michel


Để truy cập vào chiều cao của thanh trạng thái cho các thiết bị Android, chúng tôi muốn có một cách lập trình để có được nó:

Mã mẫu

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

Biến result cho chiều cao trong pixel.

Để truy cập nhanh

Enter image description here

Để biết thêm thông tin về chiều cao của Title bar, Navigation bar và Content View, vui lòng nhìn vào Kích thước màn hình thiết bị Android.


43
2017-08-27 13:12



Đúng thứ tôi cần! getResources().getDisplayMetrics().heightPixels + result cho chiều cao toàn màn hình thực tế. Câu trả lời của Dragan Marjanović cũng có tác dụng nhưng tôi thích giải pháp ngắn hơn và đơn giản hơn này. - Michel
Cách tiếp cận này đã lỗi thời như Android Marshmallow. Chiều cao thanh trạng thái có thể thay đổi từ thiết bị hoặc phiên bản Android. Sử dụng tốt hơn OnApplyWindowInsetsListener. - Heinrich


Cách đơn giản nhất:

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

42
2017-11-26 10:47



Ngoài ra, người duy nhất trong số tất cả các giải pháp này làm việc cho tôi - ShadowGod
đây là cách. (Y) - Ahsan Sher
Chức năng đơn giản để thực hiện tương tự .. Xem bài đăng này whats-online.info/science-and-tutorials/121/… - Daniel Nyamasyo


Lần xem đầu tiên (ví dụ: findViewById()) và sau đó bạn có thể sử dụng getWidth () trên chính chế độ xem.


28
2018-06-19 08:38



Đây thực sự là cách tài liệu hướng dẫn bạn làm điều đó ... nhưng nó là vô nghĩa nếu bạn KHÔNG sử dụng một khung nhìn. bạn có thể đang sử dụng thứ gì đó khác, ví dụ: mglsurfaceview. - gcb
điều này tốt hơn vì chế độ xem gốc có thể không phải là kích thước của màn hình. Nhưng hãy chắc chắn rằng điều này được thực hiện tại một điểm mà khung nhìn mà bạn đang truy vấn kích thước đã được sắp xếp, thường sẽ không nằm trong onCreate (). Bạn có thể sử dụng gọi lại tùy chỉnh từ onWindowFocusChanged (boolean hasFocus) sẽ được gọi sau khi tất cả các chế độ xem đã được đo và cứ như vậy, đảm bảo bạn sẽ không nhận được thứ nguyên không chính xác cho chế độ xem mà bạn quan tâm ... - Dori


Tôi có hai chức năng, một cho việc gửi bối cảnh và một hàm khác nhận chiều cao và chiều rộng bằng pixel:

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

24
2017-10-17 14:44



Bạn cần phải thêm @SuppressLint("NewApi") ngay phía trên chữ ký hàm để có thể biên dịch. - Adil Malik
Tôi nghĩ tốt hơn là nên lấy chiều cao và chiều rộng trong một lần thay vì trong các cuộc gọi riêng biệt tới API vì nếu không chúng có thể không đồng bộ. Điều này có thể xảy ra nếu hướng màn hình đang thay đổi trong khi mã của bạn đang chạy. - Sam


Để mở rộng động bằng cách sử dụng XML, có một thuộc tính được gọi là "android: layout_weight"

Ví dụ bên dưới, được sửa đổi từ phản hồi của đồng bộ trên chủ đề này, hiển thị nút chiếm 75% màn hình (weight = .25) và chế độ xem văn bản chiếm 25% còn lại của màn hình (weight = .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
2017-12-22 06:11