I've learned a lot. It turns out that Android screen adaptation can be played like this

I've learned a lot. It turns out that Android screen adaptation can be played like this

Why screen adaptation?

Fragmentation

  • Brand model fragmentation
  • Screen size fragmentation
  • Operating system fragmentation

In order to ensure that users get a consistent user experience and that a certain element has the same display effect on Android phones of different sizes and resolutions, we need to perform screen adaptation.

Basic Concepts

Screen size

Screen size refers to the length of the screen diagonal, measured in inches, 1 inch = 2.54 cm

Screen resolution

The total number of pixels in the horizontal and vertical directions of the mobile phone. The unit is pixel. 1px = 1 pixel. For example, 1080x1920 means there are 1080 pixels in the width direction and 1920 pixels in the height direction.

Screen pixel density

The number of pixels per inch is measured in dpi, dots per inch. For simplicity, Android groups all screen densities into six general densities: low, medium, high, extra high, extra extra high, and extra extra extra high.

  • ldpi(low)~120dpi
  • mdpi(medium)~160dpi
  • hdpi (high) ~ 240dpi
  • xhdpi (ultra high) ~ 320dpi
  • xxhdpi (super high) ~ 480dpi
  • xxxhdpi (super super high) ~ 640dpi

dpi_example

Screen density independent pixel dp (dip)

Density Independent Pixels, that is, density-independent pixels.

  • 160dpi, 1dp = 1px
  • 240dpi, 1dp = 1.5px
  • 320dpi, 1dp = 2px
  • 480dpi, 1dp = 3px
  • 640dpi, 1dp = 4px

  • The effect of using px on low, medium and high screen densities

density-test-bad

  • Effect of using dp on low, medium and high screen densities

dimen_example2

Independent scale pixel sp

Scale Independent Pixels, also known as sp or sip.

This unit is used to set the text size during Android development. It can be scaled according to the font size option. It is recommended to use 12sp, 14sp, 18sp, and 22sp as the font size. It is not recommended to use odd numbers and decimals, which can easily cause loss of precision. Fonts smaller than 12sp will be too small for users to see clearly.

Screen adaptation and picture adaptation

When designing icons, the five mainstream pixel densities (mdpi, hdpi, xhdpi, xxhdpi and xxxdpi) should be scaled in the ratio of 2:3:4:6:8. For example, a launcher image ic_launcher.png has the following sizes in each pixel density folder:

  • ldpi(low)
  • mdpi(medium)48*48
  • HDPI (high) 72*72
  • xhdpi (ultra high) 96*96
  • xxhdpi (super high) 144*144
  • xxxhdpi (super super high) 192*192

Problems

  • Producing a set of images for each resolution adds a lot of work to the artist or designer
  • The apk package of the Android project file becomes very large

Workaround

Android SDK loading picture process

  • The Android SDK will automatically select the corresponding resource file for rendering and loading according to the screen density. For example, if the SDK detects that the resolution of your phone is xhdpi, it will first look for the corresponding image resource in the xhdpi folder;
  • If there is no image resource in the xhdpi folder, it will search in a folder with a higher resolution, such as xxhdpi, until it finds an image resource with the same name and scales it down to an xhpi image;
  • If the image is still not found when searching upwards, it will search in low-resolution folders, such as hdpi, until it finds an image resource with the same name and scales it up to an xhpi image.

According to the process of loading pictures, it can be concluded that theoretically it is enough to provide a set of pictures.

So which resolution specification should be provided?

In principle, the higher the better, combined with the current mainstream resolution screen

Automatically stretch images

ninepatch_raw

ninepatch_examples

Screen adaptation layout adaptation

Layout parameters

Use wrap_content, match_parent, layout_weight.

Use of weight

weight_examples

  • When layout_width is 0dp, layout_weight is 1 and 2 respectively
  1. <LinearLayout
  2. android:layout_width= "match_parent"  
  3. android:layout_height= "wrap_content"  
  4. android:orientation= "horizontal" >
  5.  
  6. <Button
  7. android:layout_width= "0dp"  
  8. android:layout_height= "wrap_content"  
  9. android:layout_weight= "1"  
  10. android:text= "weight = 1" />
  11.  
  12. <Button
  13. android:layout_width= "0dp"  
  14. android:layout_height= "wrap_content"  
  15. android:layout_weight= "2"  
  16. android:text= "weight = 2" />
  17. </LinearLayout>

When layout_width is match_parent, layout_weight is 1 and 2 respectively

  1. <LinearLayout
  2. android:layout_width= "match_parent"  
  3. android:layout_height= "wrap_content"  
  4. android:orientation= "horizontal" >
  5.  
  6. <Button
  7. android:layout_width= "match_parent"  
  8. android:layout_height= "wrap_content"  
  9. android:layout_weight= "1"  
  10. android:text= "weight = 1" />
  11.  
  12. <Button
  13. android:layout_width= "match_parent"  
  14. android:layout_height= "wrap_content"  
  15. android:layout_weight= "2"  
  16. android:text= "weight = 2" />
  17. </LinearLayout>

Calculation of weight

Width = original width + weight ratio * remaining width

  • When layout_width is 0dp, layout_weight is 1 and 2 respectively

First button: width = 0 + 1/3 * screen width = 1/3 screen width

Second button: width = 0 + 2/3 * screen width = 2/3 screen width

  • When layout_width is match_parent, layout_weight is 1 and 2 respectively

First button: Width = screen width + 1/3 (screen width - 2 screen widths) = 2/3 screen width

Second button: Width = screen width + 2/3 (screen width - 2 screen width) = 1/3 screen width

Layout Usage

Use relative layout and disable absolute layout.

Qualifiers

Size Qualifiers

  • On a smaller mobile screen, load the layout folder layout
  • On tablet and TV screens (>7 inches), load the layout from the layout-large folder
  • Before Android 3.2

Minimum Width Qualifier

  • On a smaller mobile screen, load the layout folder layout
  • For a standard 7-inch tablet (whose minimum width is 600 dp), load the layout in the layout-sw600dp folder
  • In Android 3.2 and later versions

Layout Aliases

  • Single panel (default) layout for mobile phones: res/layout/activity_main.xml
  • Dual-panel layout for tablets > 7 inches (before Android 3.2): res/layout-large/activity_main.xml
  • Adapt to the dual-panel layout of tablets with size > 7 inches (Android 3.2 and later): res/layout-sw600dp/activity_main.xml

The XML contents of the two files are exactly the same, which will lead to duplication of file names and a series of maintenance problems. When modifying one file, you may forget to modify the other. So in order to solve this duplication problem, we introduced layout aliases.

  • Single panel (default) layout for mobile phones: res/layout/activity_main.xml
  • Adapt to the dual-pane layout of tablets with size > 7 inches: res/layout/activity_twopanes.xml
  • resalues/layout.xml
  1. <?xml version= "1.0" encoding= "utf-8" ?>
  2. <resources>
  3. <item name = "main" type= "layout" >@layout/activity_main</item>
  4. </resources>
  • resalues-large/layout.xml
  1. <?xml version= "1.0" encoding= "utf-8" ?>
  2. <resources>
  3. <item name = "main" type= "layout" >@layout/activity_twopanes</item>
  4. </resources>
  • resalues-sw600dp/layout.xml
  1. <?xml version= "1.0" encoding= "utf-8" ?>
  2. <resources>
  3. <item name = "main" type= "layout" >@layout/activity_twopanes</item>
  4. </resources>
  • setContentView(R.layout.main);

Screen orientation qualifiers

  • res/layout-land
  • res/layout-port
  • res/layout-sw600dp-land
  • res/layout-sw600dp-port

Screen adaptation: dimen adaptation

  • Nexus 4 (4.7 inches 768x1280: xhdpi)

Nexus S (4 inches 480x800: hdpi)

dimen_example2

Even if we use dp, it still cannot solve the problem of screen resolution adaptation. We can create different dimen values ​​for different screens.

  • resalues/dimens.xml
  1. <resources>
  2. <dimen name = "button_length_1" >180dp</dimen>
  3. <dimen name = "button_length_2" >160dp</dimen>
  4. </resources>
  • resalues-480x800/dimens.xml
  1. <resources>
  2. <dimen name = "button_length_1" >113dp</dimen>
  3. <dimen name = "button_length_2" >100dp</dimen>
  4. </resources>

Screen adaptation percentage layout

  • Official Documentation
  • Github Sample
  1. <?xml version= "1.0" encoding= "utf-8" ?>
  2. <android.support.percent.PercentRelativeLayout
  3. xmlns:android= "http://schemas.android.com/apk/res/android"  
  4. xmlns:app= "http://schemas.android.com/apk/res-auto"  
  5. android:layout_width= "match_parent"  
  6. android:layout_height= "wrap_content" >
  7.  
  8. <Button
  9. android:layout_width= "0dp"  
  10. android:layout_height= "wrap_content"  
  11. android:text= "30%"  
  12. app:layout_widthPercent= "30%" />
  13.  
  14. <Button
  15. android:layout_width= "0dp"  
  16. android:layout_height= "wrap_content"  
  17. android:layout_alignParentRight= "true"  
  18. android:text= "20%"  
  19. app:layout_widthPercent= "20%" />
  20.  
  21. </android.support.percent.PercentRelativeLayout>

Screen Adaptation - Adaptive User Interface

newsreader_land

newsreader_port

When NewsReader is in landscape mode, it has two panels, with HeadLinesFragment on the left and ArticleFragment on the right. Clicking on a news title switches the content of ArticleFragment. When NewsReader is in portrait mode, it has a single panel, with only HeadLinesFragment. Clicking on a news title switches to ArticleActivity to display the news content. Therefore, to achieve such landscape and portrait adaptation, it is not possible to achieve it only through layout. Different business logic processing also requires writing code to complete it. This is our adaptive user interface.

Using layout aliases

  • resalues/layouts.xml
  1. <resources>
  2. <item name = "main_layout" type= "layout" >@layout/onepane_with_bar</item>
  3. <bool name = "has_two_panes" > false </bool>
  4. </resources>
  • resalues-sw600dp-land/layouts.xml
  1. <resources>
  2. <item name = "main_layout" type= "layout" >@layout/twopanes</item>
  3. <bool name = "has_two_panes" > true </bool>
  4. </resources>
  • resalues-sw600dp-port/layouts.xml
  1. <resources>
  2. <item name = "main_layout" type= "layout" >@layout/onepane</item>
  3. <bool name = "has_two_panes" > false </bool>
  4. </resources>

Determine whether it is a single-sided or double-sided panel

  1. View articleView = findViewById(R.id.article);
  2. mIsDualPane = articleView != null && articleView.getVisibility() == View .VISIBLE; //If ArticleFragment can be found, it is a dual panel

Different business logic of single and double panels

  1. public void onHeadlineSelected( int   index ) {
  2. mArtIndex = index ; if (mIsDualPane) {
  3.  
  4. // display it on the article fragment
  5. mArticleFragment.displayArticle(mCurrentCat.getArticle( index ));
  6. } else {
  7.  
  8. // use separate activity
  9. Intent i = new Intent(this, ArticleActivity.class);
  10. i.putExtra( "catIndex" , mCatIndex);
  11. i.putExtra( "artIndex" , index );
  12. startActivity(i);
  13. }
  14. }

<<:  How to use ADB, the Android development debugging tool

>>:  Android dynamic loading: DL framework

Recommend

How to write a product promotion plan?

Entering 2018, major companies have begun to form...

In "Nezha 2", why did General Octopus dare to roast his own "feet" to eat?

Review expert: Li Yingchao, Director of the Scien...

iOS 18 hidden feature, supports T9 dialing!

In the first beta version of iOS 18, Apple finall...

5 great file managers for Android TV

[51CTO.com Quick Translation] Android TV is a TV ...

Why is cancer discovered in the late stage?

Speaking of cancer, what I remember most vividly ...

Three directions for building a brand’s own broadcast matrix account

Before we knew it, it is already June. With the a...

Win2K Server FAQ?

1. Question: My machine has multiple IP addresses...

Individual exoskeleton! Let the "future soldier" have steel bones?

Exoskeleton, in its original definition, is simpl...

How much does it cost to join a photography mini program in Tangshan?

How much does it cost to join a photography mini ...

How to do data analysis for information flow promotion? Avoid these 4 pitfalls!

If you work in bidding, how can you grow into a p...

Using RxJava to quickly obtain massive data

Imagine that when you need some dynamic data, you...