Android screen adaptation solution, android adaptation

Source: Internet
Author: User

Android screen adaptation solution, android adaptation

  • 1. Let's talk about how to do it first. I will explain it later:
  • 2. Now let's explain why we should put these three sets:
    • These three sets are actually based on the content. Why can these two sets be adapted to mainstream resolutions?
    • So we can use two types of dimens. Why should we use three sets? Why should the default dimens be hdpi?
  • 3. Image adaptation
  • 4. Finally, let's talk about the existing adaptation solutions.
  • 5. Attach the dimens conversion code
  1. Let's talk about how to do it first. I will explain it later:

1. dp is used for all units. The layout is completed with the contents of the package and the parent form and weight filled.

2. The dimens file is used for adaptation. Three sets are required, and landscape screens are not considered.

2.1 set the default dimens. xml parameter to hdpi-compatible parameters;

2.2 put dimens. xml of hdpi with parameters adapted to hdpi;

2.3 set dimens. xml of xhdpi to parameters that are compatible with xhdpi;

3. During adaptation, only a set of xhdpi dimens files are perfectly completed, and hdpi files are generated through code, because in dp, they have a fixed proportional relationship and the code will be pasted later.

 

2. Now let's explain why we should put these three sets:

Post a basic knowledge:

Ldpi 1dp = 0.75px 320*240 160dp = 120 pxmdpi 1dp = 1px 480*320 160dp = 160 pxhdpi 1dp = 1.5px 800*480 160dp = 240 pxxhdpi 1dp = 2px 1280*720 160dp = 320px <360px 180dp = 360 pxxxhdpi 1dp = 3px 1920*1080 160dp = 480px <540px 180dp = 540px These three sets are actually based on the content. Why can these two sets be adapted to mainstream resolutions?Ldpi, mdpi, and hdpi are a group. xhdpi and xxhdpi are a group. From the basic knowledge posted above, we can see that 160dp is under ldpi, mdpi, and hdpi, all are half of the screen width, that is to say, in the unit of dp, the screen display effect is the same in these three resolutions; 180dp achieves the same effect in xhdpi and xxhdpi, the same is true. So we can use two types of dimens. Why should we use three sets? Why should the default dimens be hdpi?

First, let's talk about the test results:

1. If the dimens. xml file corresponding to ldpi and mdpi does not exist, the default dimens. xml file is loaded.

2. hdpi, xhdpi, and xxhdpi load the latest dimens. xml file.

The following is the test process:

My test dimens:

-- Default dimens. xml

<resources>    <dimen name="activity_horizontal_margin">5dp</dimen>    <dimen name="activity_vertical_margin">5dp</dimen></resources>

-- Dimens. xml of hdpi:

<resources>    <dimen name="activity_horizontal_margin">50dp</dimen>    <dimen name="activity_vertical_margin">50dp</dimen></resources>

-- Dimens. xml of xhdpi:

<resources>    <dimen name="activity_horizontal_margin">500dp</dimen>    <dimen name="activity_vertical_margin">100dp</dimen></resources>

Test layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"                android:layout_width="match_parent"                android:layout_height="match_parent">    <TextView        android:layout_centerInParent="true"        android:background="#000000"        android:layout_width="@dimen/activity_horizontal_margin"        android:layout_height="@dimen/activity_vertical_margin"/></RelativeLayout>

Effects on mobile phones with different resolutions: (for better looks, I have stretched the image size), the following are: ldpi, mdpi, hdpi, hdpi (after deleting the dimens corresponding to hdpi ), xhdpi, xxhdpi

(Ldpi) (mdpi) (hdpi) hdpi (after the dimens corresponding to hdpi is deleted) (xhdpi) (xxhdpi)

Analysis result:

1. When ldpi and mdpi do not have corresponding dimens, the default dimens will be loaded. Ldpi and mdpi can share one set. Therefore, the default dimens standard is hdpi.

2. hdpi, xhdpi, and xxhdpi load the nearest dimens file. Therefore, after deleting the corresponding hdpi, The dimens of xhdpi is loaded. Therefore, we need to put a set of hdpi dimens.

3. xhdpi and xxhdpi use a set of standards, and they will load the latest. Therefore, we need to put a set of xhdpi.

 

3. Image adaptation

There are also two considerations

1. Large images with complex content 2. Small images and big images with simple content

According to the Basic Knowledge posted above, ldpi, mdpi and hdpi share the same aspect ratio, while xhdpi and xxhpdi share the same aspect ratio.

 

Therefore, the solution for the image part is:

1. Small pictures and big pictures, but the content is simple:

We will write down the control of the image to make the xy of the image adapt to the control, deformation occurs. You only need to cut a set of images, so that the image will be stretched, but the large image, such as solid color, cannot be stretched, and the small image is not obviously stretched. So do it.

 

Therefore, the solution for creating a thumbnail or a large image with simple content is to write dead controls so that the xy of the image can adapt to the controls.

2. Large images with complex content:

This image has obvious tensile deformation, so we need to deal with different resolutions:

Specifically, xhdpi (1280*720) and xxhdpi (1920*1080) are proportional to their length and width scaling, both of which are 1.5. So they can share a set of images. Put it in the drawable directory corresponding to xhdpi or the drawable directory corresponding to xxhdpi.

Hdpi, mdpi, and ldpi are out of proportion. To achieve the best adaptation effect, we need to adapt the three sets separately, but I think the current market is the mobile phone situation, we can adapt to hdpi.

Therefore, the big picture and complex solution is to adapt to two sets: xhdpi and hdpi.

 

(Ps: the native layout adaptation of the app is discussed here. Therefore, it is not applicable to scenarios where the filled images are dynamically changed and the length and width are not proportional. For example, when a user uploads an image, here we have to do a lot of processing for robustness, not in the scope of the discussion)

4. Finally, let's talk about the existing adaptation solutions.

In addition to dimens adaptation, there is also a layout file adaptation solution, through the Code dynamic settings solution (I used a GIF image on the startup interface before, I used dynamic settings)

 

5. Attach the dimens conversion code

I will not describe the basic concepts of px, dp, sp, dimens, and weight here.

Code for converting dimens: old is compatible with xhdpi. The conversion ratio is that half of the xhdpi screen is 180dp divided by half of the hdpi screen is 1.125 of that obtained by 160dp. in this case, you only need to perfectly adapt to a set of xhdpi and then generate hdpi.

package convert;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;public class DimensTools {     static String oldFilePath = "src/convert/dimens.xml";          static String filePathHdpi="src/convert/dimensHdpi.xml";            static float changes = 1.125f;     public static void main(String[] args) {          String st = convertStreamToString(oldFilePath, changes);          DeleteFolder(filePathHdpi);          writeFile(filePathHdpi, st);     }     public static String convertStreamToString(String filepath, float f) {          StringBuilder sb = new StringBuilder();          try {               BufferedReader bf = new BufferedReader(new FileReader(filepath));               String line = null;               System.out.println("q1");               String endmark = "dp</dimen>";               String startmark = ">";               while ((line = bf.readLine()) != null) {                    if (line.contains(endmark)) {                         int end = line.lastIndexOf(endmark);                         int start = line.indexOf(startmark);                         String stdp = line.substring(start + 1, end);                         //int dp = Integer.parseInt(stpx);                         float dp=Float.parseFloat(stdp);                         //float newdp =  ((float) dp / f);                                                  System.out.println("dp:"+dp);                                                  float newdp=dp/f;                                                  System.out.println("newdp:"+newdp);                                                  String dpStr=String.valueOf(dp);                         String newline;                         if(dpStr.contains(".0")){                             int x=dpStr.indexOf(".");                             System.out.println("x:"+x);                             dpStr= dpStr.substring(0,x);                             newline= line.replace(dpStr + "dp", newdp + "dp");                         }else{                             newline = line.replace(dp + "dp", newdp + "dp");                         }                                                  System.out.println("newline:"+newline);                         sb.append(newline + "\r\n");                    } else {                         sb.append(line + "\r\n");                    }               }              // System.out.println(sb.toString());          } catch (IOException e) {               e.printStackTrace();          }          return sb.toString();     }     public static boolean DeleteFolder(String sPath) {          File file = new File(sPath);          if (!file.exists()) {                return true;          } else {               if (file.isFile()) {                     return deleteFile(sPath);               } else {                // return deleteDirectory(sPath);               }          }          return false;     }     public static void writeFile(String filepath, String st) {          try {               FileWriter fw = new FileWriter(filepath);               BufferedWriter bw = new BufferedWriter(fw);               bw.write(st);               bw.flush();               bw.close();          } catch (IOException e) {               e.printStackTrace();          }     }     public static boolean deleteFile(String sPath) {          boolean flag = false;          File file = new File(sPath);          if (file.isFile() && file.exists()) {               file.delete();               flag = true;          }          return flag;     }}

 

Finally, I am exploring for myself. If you have any questions, please kindly advise.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.