This article from http://blog.csdn.net/liuxian13183/, reference must indicate the source!
There are two methods:
The first method is to obtain the Diaplay object through the WindowManager interface and obtain the Diaplay object through the Display object.
WindowManager manager = (WindowManager) context
. GetSystemService (Context. WINDOW_SERVICE );
Display display = manager. getDefaultDisplay ();
DisplayMetrics outMetrics = new DisplayMetrics ();
Display. getMetrics (outMetrics );
ScreenHeight = outMetrics. heightPixels;
ScreenWidth = outMetrics. widthPixels;
// ScreenHeight = display. getHeight (); this method has been deprecated
// ScreenWidth = display. getWidth (); this method has been deprecated
Or
From the source code, take height as an example:
Private final Point mTmpPoint = new Point ();
public int getHeight() { synchronized (mTmpPoint) { long now = SystemClock.uptimeMillis(); if (now > (mLastGetTime+20)) { getSizeInternal(mTmpPoint, true); mLastGetTime = now; } return mTmpPoint.y; } }It is mainly used to find the y coordinate of mTmpPoint.
private void getSizeInternal(Point outSize, boolean doCompat) { try { IWindowManager wm = getWindowManager(); if (wm != null) { wm.getDisplaySize(outSize); CompatibilityInfo ci; if (doCompat && (ci=mCompatibilityInfo.getIfNeeded()) != null) { synchronized (mTmpMetrics) { mTmpMetrics.noncompatWidthPixels = outSize.x; mTmpMetrics.noncompatHeightPixels = outSize.y; mTmpMetrics.density = mDensity; ci.applyToDisplayMetrics(mTmpMetrics); outSize.x = mTmpMetrics.widthPixels; outSize.y = mTmpMetrics.heightPixels; } } } else { // This is just for boot-strapping, initializing the // system process before the window manager is up. outSize.x = getRawWidth(); outSize.y = getRawHeight(); } if (false) { RuntimeException here = new RuntimeException("here"); here.fillInStackTrace(); Slog.v(TAG, "Returning display size: " + outSize, here); } if (DEBUG_DISPLAY_SIZE && doCompat) Slog.v( TAG, "Returning display size: " + outSize); } catch (RemoteException e) { Slog.w("Display", "Unable to get display size", e); } }
Then we found that setting metrics through the CompatibilityInfo object is one method, and the other is getRawHeight ()
public int getRawHeight() { int h = getRawHeightNative(); if (DEBUG_DISPLAY_SIZE) Slog.v( TAG, "Returning raw display height: " + h); return h; } private native int getRawHeightNative();The native method is implemented at the underlying layer.
Method 2: Use the Resource object to obtain DisplayMetrics.
DisplayMetrics metrics = context. getResources (). getDisplayMetrics ();
ScreenHeight = metrics. heightPixels;
ScreenWidth = metrics. widthPixels;
In general, DisplayMetrics needs to be obtained. Let's take a look at its composition:
/** * Standard quantized DPI for low-density screens. */ public static final int DENSITY_LOW = 120; /** * Standard quantized DPI for medium-density screens. */ public static final int DENSITY_MEDIUM = 160; /** * Standard quantized DPI for 720p TV screens. Applications should * generally not worry about this density, instead targeting * {@link #DENSITY_XHIGH} for 1080p TV screens. For situations where * output is needed for a 720p screen, the UI elements can be scaled * automatically by the platform. */ public static final int DENSITY_TV = 213; /** * Standard quantized DPI for high-density screens. */ public static final int DENSITY_HIGH = 240; /** * Standard quantized DPI for extra-high-density screens. */ public static final int DENSITY_XHIGH = 320;Default Density values
Default implementation method:
public void setToDefaults() { widthPixels = 0; heightPixels = 0; density = DENSITY_DEVICE / (float) DENSITY_DEFAULT; densityDpi = DENSITY_DEVICE; scaledDensity = density; xdpi = DENSITY_DEVICE; ydpi = DENSITY_DEVICE; noncompatWidthPixels = 0; noncompatHeightPixels = 0; }
Generally, the following aspects must be implemented to obtain the desired value.
public void setTo(DisplayMetrics o) { widthPixels = o.widthPixels; heightPixels = o.heightPixels; density = o.density; densityDpi = o.densityDpi; scaledDensity = o.scaledDensity; xdpi = o.xdpi; ydpi = o.ydpi; noncompatWidthPixels = o.noncompatWidthPixels; noncompatHeightPixels = o.noncompatHeightPixels; noncompatDensity = o.noncompatDensity; noncompatScaledDensity = o.noncompatScaledDensity; noncompatXdpi = o.noncompatXdpi; noncompatYdpi = o.noncompatYdpi; }Check the Resource class
public Resources(AssetManager assets, DisplayMetrics metrics, Configuration config, CompatibilityInfo compInfo) { mAssets = assets; mMetrics.setToDefaults(); mCompatibilityInfo = compInfo; updateConfiguration(config, metrics); assets.ensureStringBlocks(); }See updateConfiguration (config, metrics); Method
/** * Store the newly updated configuration. */ public void updateConfiguration(Configuration config, DisplayMetrics metrics) { updateConfiguration(config, metrics, null); }
/** * @hide */ public void updateConfiguration(Configuration config, DisplayMetrics metrics, CompatibilityInfo compat) { synchronized (mTmpValue) { if (false) { Slog.i(TAG, "**** Updating config of " + this + ": old config is " + mConfiguration + " old compat is " + mCompatibilityInfo); Slog.i(TAG, "**** Updating config of " + this + ": new config is " + config + " new compat is " + compat); } if (compat != null) { mCompatibilityInfo = compat; } if (metrics != null) { mMetrics.setTo(metrics); }
We will see this result, so when the Resources is formed, metrics has been written.
However, we just used this. getResouces to directly obtain the Resource object.
ContextThemeWrapper:
@Override public Resources getResources() { if (mResources != null) { return mResources; } if (mOverrideConfiguration == null) { mResources = super.getResources(); return mResources; } else { Context resc = createConfigurationContext(mOverrideConfiguration); mResources = resc.getResources(); return mResources; } }
It is mainly implemented in Context. It is estimated that native code is the only way to know how to implement it.
The problem of screen resolution is introduced here first.