// initialize the DisplayMetrics objectDisplayMetrics deviceDisplayMetrics = new DisplayMetrics();
// populate the DisplayMetrics object with the display characteristicsgetWindowManager().getDefaultDisplay().getMetrics(deviceDisplayMetrics);
// get the width and heightscreenWidth = deviceDisplayMetrics.widthPixels;screenHeight = deviceDisplayMetrics.heightPixels;
public class MainActivity extends Activity {@Overrideprotected 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.}
@Overrideprotected 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 {@Overrideprotected 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")@Overrideprotected 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;
@Overrideprotected 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.}}
@Overrideprotected 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")@Overrideprotected 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();}}
DisplayMetrics dimension = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(dimension);int w = dimension.widthPixels;int h = dimension.heightPixels;
/*** @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 deprecationreturn new int[]{d.getWidth(), d.getHeight()};}}
要使用:
int width = getScreenSize()[0];int height = getScreenSize()[1];
class KeyboardWatcher(private val layoutRooView: View) {
companion object {private const val MIN_KEYBOARD_HEIGHT = 200f}
private val displayMetrics: DisplayMetrics = layoutRooView.resources.displayMetricsprivate var stateVisible = false
var observer: ((Boolean) -> Unit)? = null
init {layoutRooView.viewTreeObserver.addOnGlobalLayoutListener {val heightDiff = layoutRooView.rootView.height - layoutRooView.heightif (!stateVisible && heightDiff > dpToPx(MIN_KEYBOARD_HEIGHT)) {stateVisible = trueobserver?.invoke(stateVisible)} else if(stateVisible) {stateVisible = falseobserver?.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 ...}
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}
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}
java
DisplayMetrics dimension = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(dimension);int w = dimension.widthPixels;int h = dimension.heightPixels;
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;}}