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

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

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


当前回答

简单的功能与较低版本兼容。

/**
 * @return screen size int[width, height]
 *
 * */
public int[] getScreenSize(){
    Point size = new Point();
    WindowManager w = getWindowManager();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2){
        w.getDefaultDisplay().getSize(size);
        return new int[]{size.x, size.y};
    }else{
        Display d = w.getDefaultDisplay();
        //noinspection deprecation
        return new int[]{d.getWidth(), d.getHeight()};
    }
}

要使用:

int width = getScreenSize()[0];
int height = getScreenSize()[1];

其他回答

我尝试了所有可能的“解决方案”,但都失败了,我注意到Elliott Hughes的“Dalvik Explorer”应用程序在任何Android设备/操作系统版本上都始终显示正确的维度。我最后看了他的开源项目,可以在这里找到: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) {
}

EDIT:略有改进的版本(避免在不受支持的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) {
}

这里是Kotlin实现中对上面一些答案的简单改编。它需要清单中如上所述的windowsSoftInput=“adjustResize”:

class KeyboardWatcher(private val layoutRooView: View) {

    companion object {
        private const val MIN_KEYBOARD_HEIGHT = 200f
    }

    private val displayMetrics: DisplayMetrics = layoutRooView.resources.displayMetrics
    private var stateVisible = false

    var observer: ((Boolean) -> Unit)? = null

    init {
        layoutRooView.viewTreeObserver.addOnGlobalLayoutListener {
            val heightDiff = layoutRooView.rootView.height - layoutRooView.height
            if (!stateVisible && heightDiff > dpToPx(MIN_KEYBOARD_HEIGHT)) {
                stateVisible = true
                observer?.invoke(stateVisible)
            } else if(stateVisible) {
                stateVisible = false
                observer?.invoke(stateVisible)
            }
        }
    }

    private fun dpToPx(valueInDp: Float): Float {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, displayMetrics)
    }
}

并使用:

val activityRootView = findViewById<ViewGroup>(R.id.activityRoot)
KeyboardWatcher(activityRootView).observer = { visible ->
    if (visible) do something here ...
}

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

创建一个类和方法,如下所示:

public MyPoint getScreenDimensionsAsPixel(Context context){
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();

        Point point = new Point();
        display.getSize(point);

        return new MyPoint(point.x, point.y);
    }

    public class MyPoint{
        private int width;
        private int height;

        public MyPoint(int width, int height) {
            this.width = width;
            this.height = height;
        }

        public int getWidth() {
            return width;
        }

        public void setWidth(int width) {
            this.width = width;
        }

        public int getHeight() {
            return height;
        }

        public void setHeight(int height) {
            this.height = height;
        }
    }

然后在代码中使用它们:

MyPoint myPoint = getScreenDimensionsAsPixel(MainActivity.this);
                Toast.makeText(MainActivity.this, "width: " + String.valueOf(myPoint.getWidth()) + "|" +
                        "height: " + String.valueOf(myPoint.getHeight()), Toast.LENGTH_LONG).show();

此函数以英寸为单位返回近似屏幕大小。

public double getScreenSize()
{
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        int width=dm.widthPixels;
        int height=dm.heightPixels;
        int dens=dm.densityDpi;
        double wi=(double)width/(double)dens;
        double hi=(double)height/(double)dens;
        double x = Math.pow(wi,2);
        double y = Math.pow(hi,2);
        double screenInches = Math.sqrt(x+y);
        return screenInches;
}