background
Screen adaptation has always been a very important part of Android, but there are a lot of trivial things involved. This article will take you through the various aspects of screen adaptation, and you will be able to answer the following questions:
-
What is the difference between DPI, PPI, Density, DP and PX?
-
Why put the image in the maximum resolution directory for adaptation?
-
Will the width and height change after loading the same image into memory if it is placed in a different drawable directory?
-
Will the width and height change after the pictures are placed in the xHDPI directory and loaded into memory by phones with different screen pixel densities?
-
Why does it only take 77.11K to store on the hard disk and over 30 MB to store in memory?
-
Why is it best to only place app ICONS in the MiPMap directory?
-
Will manually changing the screen pixel density affect app loading fixed resolution folders?
-
Comparison of mainstream adaptation schemes?
What is the difference between DPI, PPI, Density, DP and PX?
DPI = Dots Per Inch, PPI = Pixel Per Inch The difference between Dot, which refers to every physical Dot on the display, and Pixel, which refers to the smallest unit of screen resolution. Can these two be different? Will! Dot is not the same as pixel when a pixel requires more than one physical dot on the screen to display. Another term for this is DPPX (dot per Pixel), which is how many points there are in each pixel. On most monitors, a pixel is a dot, but some better screens and some mobile phones have a DPPX greater than 1. Mac Retina, iPhone, HTC One, etc. Generally speaking, dPI and PPI are equivalent for Android phones. So we just call them screen pixel density. The lower the screen density, the fewer pixels there will be in a given physical area. The general density in Android is as follows:
ldpi |
Suitable for resources with low density (LDPI) screens (~ 120dpi). |
---|---|
mdpi |
Resources that apply to medium density (MDPI) screens (~ 160dpi) (this is the baseline density). |
hdpi |
Suitable for high-density (HDPI) screen (~ 240dpi) resources. |
xhdpi |
Suitable for high (XHDPI) density screen (~ 320dpi) resources. |
xxhdpi |
Suitable for super ultra High density (XXHDPI) screen (~ 480dpi) resources. |
xxxhdpi |
Suitable for super ultra High density (XXXHDPI) screen (~ 640dpi) resources. |
nodpi |
Applies to all density resources. These are density-independent resources. Resources marked with this qualifier are not scaled regardless of the current screen density. |
tvdpi |
Suitable for resources with screens with densities between MDPI and HDPI (about 213dpi). This is not in the “primary” density group. It’s mostly used for TVS, and most apps don’t need it. For most applications, providing MDPI and HDPI resources will suffice, and the system will scale them as appropriate. If you find it necessary to provide a TVDPI resource, its size should be determined by a coefficient of 1.33*mdpi. For example, if an image is 100px x 100px on the MDPI screen, it should be 133px x 133px on the TVDPI screen. |
anydpi |
This qualifier applies to all screen densities and takes precedence over other qualifiers. This is very applicableVectors can draw objects.This configuration is new in API level 21 |
nnndpi |
Used to represent non-standard density, where*nnn* Is a positive integer screen density. This qualifier does not apply in most cases. Using standard density storage partitions can significantly reduce the overhead associated with supporting screen density for various devices on the market. |
To create alternate graphable bitmap resources for different densities, you should follow a 3:4:6:8:12:16 scaling ratio between the six main densities. For example, if you have a graphable bitmap resource that has a size of 48×48 pixels on a medium-density screen, it should have a size of 48×48 pixels on a screen of various other densities:
- 36×36 (0.75x) – Low density (LDPI)
- 48×48 (1.0x baseline) – Medium density (MDPI)
- 72×72 (1.5x) – High density (HDPI)
- 96×96 (2.0x) – Ultra High Density (XHDPI)
- 144×144 (3.0x) – Ultra High Density (XXHDPI)
- 192×192 (4.0x) – Ultra Ultra High Density (XXXHDPI)
Density: The “density” value obtained with the code context.getResources().getDisplayMetrics().density. The value obtained by this method is actually a result value equivalent to “DPI / 160”.
Dp: density-independent pixel, 1 dp is approximately equal to medium density screen (160dpi; 1 pixel on the “base” density). If you want to display roughly the same visible size on screens of different densities, you should use density-independent pixel DP.
- On a device with a resolution of 320 x 480 (dPI 160), 160DP is equivalent to 160px, with buttons taking up half the screen width.
- On a device with a resolution of 640 x 960 (dPI of 320), 160DP is equivalent to 320px, and the buttons still take up half the screen width.
Px: in fact, it is the unit of pixels. For example, 800*400 is the unit of PX in the mobile phone resolution list
1dp = (dpi / 160)px, dp = px/density. The purpose of Android density is to make screen adaptation.
Will the width and height change after loading the same image into memory if it is placed in a different drawable directory?
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/dev"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Copy the code
Java code:
Drawable drawable = imageView.getDrawable();
if(drawable ! =null) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
Bitmap bitmap = bitmapDrawable.getBitmap();
Log.d(TAG, " width = " + bitmap.getWidth() + " height = " + bitmap.getHeight());
}
Copy the code
Original size: 352 x 484
In the xhdPI directory on the 320dpi (xHDPI) device, the width and height of the image obtained is 352 * 484, because the device is xHDPI and xHDPI directory corresponding, so the width and height of the image obtained naturally does not change.
The width and height of the picture obtained in the MDPI directory is 704 * 968. It can be understood that if the picture is placed in the MDPI directory, the system will enlarge the picture in the MDPI by default because the picture in THE XHDPI is twice that in the MDPI. So the Bitmap is twice as wide and twice as high.
In the xxHPI directory, the width and height of the image is 235 * 323, 253 = 352 * (2/3) 323 = 484 * (2/3)
It should also be noted that drawable and drawable-mdpi are of the same size, because drawable- MDpi is the default pixel density of the system, and other pixel densities are based on it. When only images exist in drawable, if this image is used, Then it will scale to the drawable- MDpi scale.
Why put the image in the maximum resolution directory for adaptation?
The calculation formula of memory footprint mentioned above: width * height * unit pixel takes up bytes. If you put it on a low resolution phone, the width and height of the Bitmap will increase, so does the memory size increase? The answer is yes, because memory is only related to the width and height of the image, in bytes per pixel. The same image in different directories will generate bitmaps of different sizes. The larger the width and height of the Bitmap, the larger the memory footprint, and the lower the resolution, the larger the memory footprint. Therefore, in order to fit (if there is only one folder), try to place the image under xxXhdPI.
Will the width and height change after the pictures are placed in the xHDPI directory and loaded into memory by phones with different screen pixel densities?
Bitmap size: 352 * 484, device 320dpi (xhdPI)
In the xhdPI directory on the 320dpi (xHDPI) device, the width and height of the image obtained is 352 * 484, because the device is xHDPI and xHDPI directory corresponding, so the width and height of the image obtained naturally does not change.
Original Bitmap size: 352 * 484, device 480dpi (xxhdPI), placed in xhdPI directory
When using xxHDPI equipment, to obtain the width and height of the picture is 528 * 726, that is, the width and height are multiplied by 3/2, it can be seen that in the encounter with a higher resolution (screen density mobile phone), the width and height of the picture will be proportional to enlarge, if the use of MDPI equipment is reduced by half;
If I put the picture in the mdPI directory (original size) and use xxhdPI device, the width and height of the picture is 1056 * 1452, and the enlargement is 3 times.
summary
On the same device, images are placed in a directory with successively lower resolution to higher resolution, and the Bitmap size of the image decreases continuously.
In the same resolution directory, running from low resolution to high resolution devices, the Bitmap size of the image increases.
Why does it only take 77.11K to store on the hard disk and over 30 MB to store in memory?
Because it’s not the same thing
Stored in hard disk image files and compressed rules according to their respective compression of the lossy compression like Jpeg image format, the most commonly used word variable length coding of harvard, coding, will use the harvard tree, which is the optimal binary tree, according to the frequency of the occurrence of certain data coding, data so as to reduce the amount of hard disk size.
For example, the sequence “10111” has the highest probability of appearing in the binary data of the picture, so we can use “01” to replace this data. The original 5 bits of data can be represented by 2 bits, which is the compression rate of 60%. Of course, this is only for example, in practice you need to consider the “isoprefix principle” and other basic coding principles.
Read into memory and if the image is different, because we need each pixel can be displayed on the screen, so will get each pixel are loaded into memory, not to compress the same pixel or replaced, so you should also understand the aforementioned Bitmap of the origin of the formula to calculate the size of the memory.
Will changing screen pixel density affect app loading fixed resolution folders?
According to the test, when pictures with different contents but the same name are placed under different resolutions, changing the screen pixel density does not affect the app to load folders with fixed resolutions, that is to say, pictures with the same contents are still loaded.
Adb shell WM Density // Adb shell WM Density 640 // Set the screen pixel density to 640 adb shell WM Density reset // reset the initial pixel densityCopy the code
It is best to place only the app icon in the MiPmap directory
Mipmap translates to texture mapping technology, and ICONS in miPMap folders are optimized using miPMap texture technology. Mipmap texture technology is the most effective way to solve the relationship between texture resolution and viewpoint distance. It first compresses the image into many gradually shrinking images. For example, a 64 * 64 image will produce seven images of 64 * 64,32 * 32,16 * 16,8 * 8,4 * 4,2 * 2,1 * 1. When 20 * 20 pixels need to be drawn on the screen, The program simply uses 32 by 32 and 16 by 16 images to calculate an image that will be displayed as 20 by 20, which is much better and faster than the original 32 by 32 image alone.
Here’s an official explanation of why you want to place your app icon in the Mipmap directory:
As with all other bitmap resources, you need to provide a density-specific version of the application icon. However, Some desktop apps display app ICONS as much as 25% larger than the density level of the device requires (However, Some app launchers display your app icon as much as 25% larger than what’s called for by the device’s density bucket).
For example, if the device’s density storage partition is XXhdPI, and the maximum application icon density level you provide is drawable-xxhdpi, the launcher application will enlarge the icon, which will make it look less sharp. Therefore, you should provide a higher-density initiator icon in the mipmap-xxxhdPI directory so that the initiator can switch to xxxhdPI resources.
Because application ICONS can be enlarged like this, you should place all application ICONS in the Mipmap directory rather than in the Drawable directory. Unlike drawable directories, all MiPMap directories remain in APK, even if you build density-specific APKs. This allows the launcher application to select the best resolution icon to display on the home screen.
Pay attention to
In my opinion, we should provide images of different sizes in the miPmap folder of different resolutions, and then display the images that are not provided in MiPMap through texture mapping technology, so that the images can be displayed faster and better.
All mipmap directories will remain in APK, even if you build density-specific APK, which means that configuration like resConfigs “xhdPI” has no effect on files in the Mipmap directory. So it’s best to just put the app icon in. Because app ICONS don’t take up much space, it’s also important that they are clearly displayed.
Mainstream adaptation solutions on the market (from JessYan’s article)
Density is fixed on each device, DPI / 160 = density, the total px width of the screen/density = the total DP width of the screen. Due to the fragmentation of Android, most Android devices on the market have inconsistent aspect ratios. If we only use height or width as a reference, we can effectively avoid the layout distortion on screens with inconsistent aspect ratios.
Toutiao adaptation scheme
The principle of
- Device 1, screen width 1080px, 480DPI, total screen DP width 1080 / (480/160) = 360DP
- Device 2, screen width 1440px, 560DPI, total screen DP width 1440 / (560/160) = 411DP
You can see that the total dp width of the screen varies from device to device, but the DP value we fill in the layout is fixed
What does this lead to? Suppose we have a View with a width of 100dp in our layout. In device 1, this View is 27.8% of the entire screen width (100/360 = 0.278).
However, in device 2, the width of this View can only account for 24.3% of the entire screen width (100/411 = 0.243). It can be seen that the dp value of this View on the screen with higher pixels does not change, but its proportion to the actual screen changes greatly. Therefore, the naked eye viewing effect, It gets smaller and smaller, which leads to a big error in the traditional screen adaptation method of filling in DP.
In order to fit perfectly, we have to make sure that the View is the same proportion to the screen on any screen resolution.
So what do we do? Change the dp value of each View? It is not realistic. It is too much work to dynamically calculate the DP value of the View through code on each device.
If the DP value of each View is fixed and constant, the ratio of each View to the screen in all resolutions can be guaranteed as long as the total DP width of the screen of each device remains unchanged, so as to complete equal proportion adaptation. And if the total DP width of the screen can be guaranteed to be consistent with the width of the design drawing, then we can directly fill in the DP value according to the size of the design drawing in the layout
Total px width/density = Total DP width of the screen
In this formula we need to make sure that the total dp width of the screen is the same as the total design width and remains the same across all screen resolutions. What do we need to do? The total px width of the screen varies from device to device, and this value is bound to change, where the Toutiao formula comes in handy.
Total screen width (in pixels)/total design width (in dp) = density
In this formula, the total DP width of the screen in the above formula is replaced by the total width of the design drawing. The principle is the same. As long as the density is calculated and changed in real time according to different devices, the total width of the design drawing can be guaranteed to remain unchanged, thus the adaptation is completed.
In general, the density is changed to [the current device total screen width (in pixels)/the total design width (in dp)], the total DP number is changed (for example, the design is 375), and the DP set by View remains the same, keeping the total screen proportion occupied by View unchanged.
The advantages and disadvantages
The advantage is that the code is less intrusive and the trial-and-error cost is close to 0, but the modified density is global. When the size of the design drawing of a system control or tripartite library control differs greatly from that of our own project, this problem becomes more serious. (The solution can be based on the Activity to cancel the adaptation effect of the current Activity and use another adaptation solution).
SmallestWidth qualifier adaptation scheme (Minimum width qualifier adaptation scheme)
Speaking of which, someone will certainly mention the width and height qualifier screen adaptation, and the SmallestWidth qualifier adaptation can be thought of as an improved version of the width and height qualifier adaptation. The smallestWidth qualifier screen adaptation simply changes the value in the dimens. XML file from PX to dp. The principle and usage remains the same.
├ ─ ─ SRC/main │ ├ ─ ─ res │ ├ ─ ─ ├ ─ ─ values │ ├ ─ ─ ├ ─ ─ values - sw320dp │ ├ ─ ─ ├ ─ ─ values - sw360dp │ ├ ─ ─ ├ ─ ─ values - sw400dp │ ├ ─ ─ ├ ─ ─ values - sw411dp │ ├ ─ ─ ├ ─ ─ values - sw480dp │ ├ ─ ─ ├ ─ ─... │ ├── ├─ Values-SW640DP │ ├─ Values-SW640DP │ ├─ Values-SW640DP │ ├─ Values-SW640DPCopy the code
The principle of
The principle of the smallestWidth qualifier screen adaptation solution is also very simple. The developer first generates a series of values- SWDP folders (containing dimens.xml) in the project based on the minimum width of the mainstream screen (smallestWidth). When running the project on the device, the system will match the values in the dimens. XML text in the values-SWdp folder according to the minimum screen width of the current device (smallestWidth). It is customized according to the minimum screen width of the current device (smallestWidth), so it will definitely fit the current device.
If the system does not find a values-SWdp folder based on the minimum screen width of the current device (smallestWidth), it will look for a values-SWDP folder with a similar minimum screen width (smallestWidth). The system only looks for values- SWDP that is less than or equal to the current minimum device width (smallestWidth), which is more fault tolerant than the width and height qualifier screen adaptation, and can also generate many fewer values- SWDP folders, reducing the size of the App.
If the minimum width is 360 dp (1080 / (480/160) = 360)
Now we have figured out that the minimum width of the current device is 360 DP. We know that the system will help us match the dimens. XML file under the values-SW360DP folder according to this minimum width. If there is no values-SW360DP folder in the project, The system will match a similar values-SWdp folder
The smallestWidth qualifier screen adaptation scheme also works by using a percentage layout. If the width of a View in the layout refers to DP_100, the width of the View will be 100 1/360 of the total screen width of the current device, no matter which device it is running on. The premise is that the project provides values-SWDP corresponding to the current device screen. If there is no values-SWDP corresponding to the current device screen, the project will look for similar values-SWDP, which will cause errors.
Since the scheme is adapted with the minimum width, 360 pieces are added, but when the height to be set is greater than 360 pieces, how should it be set?
For example, if the width of the design is 375, the width of the mobile phone is 1920*1080, and dPI =480, then the value generated at 375 in the dimens. XML file in values -sw360DP is 360, then 361…. 362… All of these values are additive and this file doesn’t end at 375, so you can control when it ends! You can continue to generate a certain number of values by modifying the plug-in.
In fact, the principle of smallestWidth qualifier screen adaptation scheme is similar to Toutiao screen adaptation scheme, which dynamically adjusts the density of each device according to the width or height of the screen (how many pixels per DP of the current device screen). The smallestWidth qualifier screen adaptation scheme also dynamically adjusts the DP value per share for each device based on the screen width.
The advantages and disadvantages
Very stable, does not have any performance loss, adaptive range can be freely controlled, does not affect other third-party libraries, access costs are also very low. However, it is highly intrusive and requires a trade-off between adaptation effect and space occupation, so it cannot automatically support adaptation when switching between horizontal and vertical screens. As mentioned above, if you want to automatically support adaptation when switching between horizontal and vertical screens, you need to use values-WDP or screen orientation qualifier to regenerate a set of resource files, which will increase the size of the App again.
AndroidAutoSize
AndroidAutoSize is optimized according to toutiao adaptation scheme, AndroidAutoSize has two types of layout units to choose from, one is the main unit (DP, SP), one is the secondary unit (PT, IN, mm), two kinds of units for different application scenarios, Both of them have their own advantages and disadvantages.
The main unit: Using DP, SP as the unit for layout, the least invasive, will affect the layout effect of other tripartite library pages, tripartite library controls and system controls, but AndroidAutoSize also through this feature, ExternalAdaptManager is used to adapt a tripartite library without modifying its source code.
Deputy units: Using pt, IN, mm as the unit of layout, high intrusion, good support for the old project, does not affect the layout effect of other tripartite library pages, tripartite library controls and system controls, can completely shield all unknown and known problems caused by the modification of density. However, AndroidAutoSize will not be able to adapt to the third party library.
The principle of
For automatic parsing, use the ContentProvider, which launches the framework in its onCreate, prior to Application#onCreate. As for multithreading initialization, you can view the original text for operation.
How to adapt the tripartite library interface? (if the layout of the tripartite library page is dp and sp, if the layout is all px, then AndroidAutoSize will not be able to do so)
ExternalAdaptManager can be used when using the master unit to adapt all activities and fragments of the library without modifying the source code of the library.
Through ExternalAdaptManager# addExternalAdaptInfoOfActivity (Class, ExternalAdaptInfo) instead of implementing CustomAdapt, add custom classes and custom adaptation parameters to the method, which is shown here with detailed comments.
Instead of implementing the CancelAdapt, add the classes that need to be unadapted to the method by ExternalAdaptManager#addCancelAdaptOfActivity(Class), which is shown here, with detailed comments.
The advantages and disadvantages
It is the comprehensive expansion and optimization of Toutiao solution, which solves the pain points of Toutiao solution and is more flexible. So far, it is the most comprehensive solution.
conclusion
Screen adaptation is actually a very trivial knowledge, can really connect these knowledge points above the people are not many, this article refers to many big man’s article, thank them. Give a thumbs-up if you like
reference
Developer.android.com/guide/topic…
Developer.android.com/training/mu…
Blog.csdn.net/pdskyzcc1/a…
Juejin. Cn/post / 684490…
Blog.csdn.net/zhaokaiqian…