如何在Android中以像素为单位获取屏幕尺寸


1841

我创建了一些自定义元素,我想以编程方式将它们放置在右上角(n顶部边缘的m像素和右侧边缘的像素)。因此,我需要获取屏幕宽度和屏幕高度,然后设置位置:

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

我如何获得screenWidthscreenHeight参加主要活动?


使用dp而不是px。因为它会与其他设备扭曲你的布局..
贾瓦德·瑞伯

不要忘记将getResources()。getDisplayMetrics()。density乘以解决显示缩放问题
jmaculate 2014年

这证明投票最多的答案并不总是最好的(很多人为代表重复答案)。尝试使用Balaji.K而不是getSize和已弃用的getWidth / getHeight组合(忽略错误)getMetrics。Nik在其答案中的评论甚至说明getDisplayMetrics了考虑系统/状态栏的大小。另外,您可以使用密度作为jmaculate,而LoungeKatt解释为具有EXACT值:DisplayMetrics dm = getResources().getDisplayMetrics(); float fwidth = dm.density * dm.widthPixels;在Android v2.2(API 8)和v4.0中经过测试,结果良好,没有错误/警告
Armfoot

DisplayMetrics displaymetrics = new DisplayMetrics(); getWindowManager()。getDefaultDisplay()。getMetrics(displaymetrics); int height = displaymetrics.heightPixels; int width = displaymetrics.widthPixels;
阿扎哈尔2015年

另一种获取DisplayMetrics的方法:Resources.getSystem().getDisplayMetrics()。您不需要Context获取它们。
塔格

Answers:


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),您可以使用getWidthgetHeight现在不推荐使用的方法:

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上运行,该怎么办?
卡罗尔

52
尝试{display.getSize(size); 宽度= size.x; 高度= size.y; } catch(NoSuchMethodError e){width = display.getWidth(); 高度= display.getHeight(); }
Arnaud 2012年

248
我不明白您为什么要使用try/catch这种支票?为什么不简单地使用if (android.os.Build.VERSION.SDK_INT >= 13)所有抛出的异常呢?我认为try/catch在正常的应用程序流中,这是一种不好的做法。
Patrik

2
@ A-Live,则该应用程序也会损坏(但不会崩溃)。但是,我们的开发人员必须预先检查新的os版本,这可能只是掩盖了问题。同样,使用此参数,可以/应该用try / catch包围每几行代码,在我看来,这已经是不好的做法了。
Patrik

11
如果要获取不包括导航栏和/或通知栏的屏幕尺寸怎么办
android开发人员

374

一种方法是:

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

不建议使用它,而应尝试使用以下代码。前两行代码为您提供DisplayMetricsobjecs。这个对象包含像场heightPixelswidthPixels

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

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

14
请注意,度量标准(宽度,高度)根据设备的旋转而变化。
Tony Chan

8
指标将返回显示的大小,但是由于系统栏的原因,HoneyComb及以上版本的活动空间将小于返回的空间。
Guy

3
@Guy,这取决于您的实现。您可以隐藏状态栏:requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow()。setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
Hagai L 2012年

79
也以这种方式存在:getContext()。getResources()。getDisplayMetrics()。widthPixels
Nik

最终浮标= getResources()。getDisplayMetrics()。density; int width =(int)(metrics.widthPixels *比例+ 0.5f); -这样做时必须考虑设备密度。
被遗弃的购物车

119

它可能无法回答您的问题,但了解(当我遇到此问题时我自己也在寻找它)可能很有用(如果您需要View的尺寸,但是在尚未布局其布局时正在执行您的代码) (例如中的onCreate()),您可以设置ViewTreeObserver.OnGlobalLayoutListenerView.getViewTreeObserver().addOnGlobalLayoutListener(),然后在其中放置需要视图尺寸的相关代码。布局完成后,将调用侦听器的回调。


或只写view.post
Lukas Hanacek 2013年

view.post不能保证正常工作。这只是一个解决方法。
marsbear 2014年

@marsbear上说View.post()不能保证在哪里工作?我很好奇,因为我也依靠这种方法在布局后获取View的大小,并且没有意识到它不可靠。
2014年

@Turbo我说:p我们以前使用过这种解决方法,结果证明它是不可靠的。该解决方法基于以下假设:初始布局是在与初始化相同的UIThread内完成的。因此,您可以通过post()将代码安排在下一个UI之前运行,并且很好。事实证明,在某些情况下布局可能会花费更长的时间,并且在发布代码运行时,视图仍未布局。我现在要做的是在onCreate中添加ViewTreeObserver,并在第一个onLayout之后将其删除。在第一个onLayout期间初始化您的东西。
marsbear 2014年

@marsbear 从哪儿View得到的重要ViewTreeObserver吗?还是他们都共享同一个人?
东尼·陈

109

(2012年的答案,可能已经过时)如果要支持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

抱歉,请允许我阐明我的意思。截至
2015年

69

我尝试了所有可能的“解决方案”均未成功,但我注意到Elliott Hughes的“ Dalvik Explorer”应用在任何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) {
}

编辑:版本略有改进(避免在不受支持的OS版本上触发异常):

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
这是这里唯一考虑到窗户装饰(状态栏/菜单栏)的帖子。对我来说很棒。
安迪·科克伦

5
太棒了,但是您永远都不会期望有业务逻辑触发异常。异常触发(即使被捕获)的性能也是可怕的。另外,如果SDK_INT> 13,则您的工作量超出了需要。相反,您应该在Build.VERSION.SDK_INT上添加一些if。
Erik B

3
@Erik B,我同意。我添加了改进的版本。我还是保留了“自SDK 1起”的部分,以防万一在try / catch中出了问题(我在Android上看到了很多不好的地方,尤其是当您认为不可能出问题的时候,我想保持它的安全性:)) 。无论如何,不​​应有太多的开销,因为此计算仅应执行一次(例如,值可以保留在某些静态属性中)。
DraganMarjanović13年

8
请注意,此代码已获得GPL v3的许可,这可能会影响在生产应用中使用。
TalkLittle 2013年

GPL并依靠反射来调用将来的Android版本中可能不存在的方法。恩赫
米歇尔(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 barNavigation bar以及Content View,在亲切的样子Android设备屏幕尺寸


正是我所需要的!getResources().getDisplayMetrics().heightPixels + result给出实际的全屏高度。德拉甘·马里亚诺维奇(DraganMarjanović)的答案也有效,但我更喜欢这种更短,更简单的解决方案。
米歇尔

从Android Marshmallow开始,这种方法已经过时了。状态栏的高度可以从设备或Android版本更改。更好地使用OnApplyWindowInsetsListener
Heinrich

32

首先获取视图(例如by findViewById()),然后可以在视图本身上使用getWidth()


3
实际上,这就是文档告诉您的方式...但是,如果您不使用视图,那是毫无意义的。您可能正在使用其他工具,例如mglsurfaceview。
gcb

2
这样做更好,因为父视图可能不是显示器的大小。但是,请确保在您要查询的视图的视图已被布局的位置上完成此操作,该视图通常不在onCreate()内部。您可以使用onWindowFocusChanged(boolean 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")在函数签名上方添加才能进行编译。
阿迪尔·马里克

我认为最好一口气获得高度和宽度,而不是单独调用API,因为否则它们可能会不同步。如果在运行代码时屏幕方向发生变化,则可能会发生这种情况。
2015年

17

为了使用XML动态缩放,有一个名为“ android:layout_weight”的属性

下面的示例根据Synic在该线程上的响应进行了修改,显示了一个按钮,该按钮占据了屏幕的75%(权重= .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
这不会减少屏幕上控件的空间(例如Tablet或Nexus设备上的空间)。另外,我在10英寸平板电脑上获得的值也不同(750 vs 800),具体取决于计算完成时“活动”是否处于活动状态。但是出于我的目的,这还不错。谢谢!
Steven L


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

我发现这可以解决问题。

Rect dim = new Rect();
getWindowVisibleDisplayFrame(dim);

5
很酷,但是在源代码中关于此方法的一件令人恐惧的事情:此注释
Norbert

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)有一种不建议使用的方法,它避免了try / catch混乱:

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

对于谁在没有状态栏操作栏的情况下搜索可用的屏幕尺寸(也要感谢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

科特林

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

显然,您也可以将捆绑包中的高度也传递回来。
史蒂夫·沃林

5

如果您不希望WindowManagers,Points或Displays产生开销,则可以将XML中最顶部的View项的height和width属性获取,只要将其高度和宽度设置为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()并将返回屏幕的高度。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.