我创建了一些自定义元素,并希望以编程方式将它们放置在右上角(距离上边缘n个像素,距离右边缘m个像素)。因此,我需要获得屏幕宽度和屏幕高度,然后设置位置:

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

如何在主活动中获取screenWidth和screenHeight?


当前回答

遵循以下方法:

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

其他回答

首先获取视图(例如,通过findViewById()),然后可以对视图本身使用getWidth()。

如果您想要以像素为单位的显示尺寸,可以使用getSize:

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

如果您不在“活动”中,则可以通过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);

API等级30更新

final WindowMetrics metrics = windowManager.getCurrentWindowMetrics();
 // Gets all excluding insets
 final WindowInsets windowInsets = metrics.getWindowInsets();
 Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()
         | WindowInsets.Type.displayCutout());

 int insetsWidth = insets.right + insets.left;
 int insetsHeight = insets.top + insets.bottom;

 // Legacy size that Display#getSize reports
 final Rect bounds = metrics.getBounds();
 final Size legacySize = new Size(bounds.width() - insetsWidth,
         bounds.height() - insetsHeight);

•Kotlin版本通过扩展属性

在android中有多种实现屏幕尺寸的方法,但我认为最好的解决方案可以独立于Context实例,因此您可以在代码中的任何地方使用它。在这里,我通过kotlin扩展属性提供了一个解决方案,它可以很容易地知道以像素为单位的屏幕大小以及dp:


尺寸Utils.kt

import android.content.res.Resources
import android.graphics.Rect
import android.graphics.RectF
import android.util.DisplayMetrics
import kotlin.math.roundToInt

/**
 * @author aminography
 */

private val displayMetrics: DisplayMetrics by lazy { Resources.getSystem().displayMetrics }

val screenRectPx: Rect
    get() = displayMetrics.run { Rect(0, 0, widthPixels, heightPixels) }

val screenRectDp: RectF
    get() = displayMetrics.run { RectF(0f, 0f, widthPixels.px2dp, heightPixels.px2dp) }

val Number.px2dp: Float
    get() = this.toFloat() / displayMetrics.density

val Number.dp2px: Int
    get() = (this.toFloat() * displayMetrics.density).roundToInt()


用法:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val widthPx = screenRectPx.width()
        val heightPx = screenRectPx.height()
        println("[PX] screen width: $widthPx , height: $heightPx")

        val widthDp = screenRectDp.width()
        val heightDp = screenRectDp.height()
        println("[DP] screen width: $widthDp , height: $heightDp")
    }
}

结果:

当设备处于纵向时:

[PX] screen width: 1440 , height: 2392
[DP] screen width: 360.0 , height: 598.0

当设备处于横向时:

[PX] screen width: 2392 , height: 1440
[DP] screen width: 598.0 , height: 360.0


如果您不是kotlin的粉丝,请使用java版本:

import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.DisplayMetrics;

/**
 * @author aminography
 */
public class DimensionUtils {

    private static DisplayMetrics displayMetrics;

    private static DisplayMetrics getDisplayMetrics() {
        if (displayMetrics == null) {
            displayMetrics = Resources.getSystem().getDisplayMetrics();
        }
        return displayMetrics;
    }

    public static Rect screenRectPx() {
        return new Rect(0, 0, getDisplayMetrics().widthPixels, getDisplayMetrics().heightPixels);
    }

    public static RectF screenRectDp() {
        return new RectF(0f, 0f, px2dp(getDisplayMetrics().widthPixels), px2dp(getDisplayMetrics().heightPixels));
    }

    public static float px2dp(int value) {
        return value / getDisplayMetrics().density;
    }

    public static int dp2px(float value) {
        return (int) (value * getDisplayMetrics().density);
    }
}
DisplayMetrics dimension = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dimension);
int w = dimension.widthPixels;
int h = dimension.heightPixels;

对于使用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>