Android screen adaptation solution and android adaptation solution

Source: Internet
Author: User

Android screen adaptation solution and android adaptation solution

Reprinted please indicate the source:
Http://blog.csdn.net/lmj623565791/article/details/45460089;
This article is from: [Zhang Hongyang's blog]

1. Overview

During Android development, you will surely feel that screen adaptation is especially painful. If we look at this problem from another perspective, do you know whether you have learned about web Front-end development or whether you are familiar with web pages, in fact, the adaptation problem also exists theoretically in the design of web pages. Why? The resolution of the computer's display, including the resolution of the mobile phone, I dare say that the resolution type is much higher than the resolution of the Android device, so there is a strange phenomenon:

Why have the Web page designers never said that Nima is difficult to adapt?

So what is the reason for the design of web pages to provide users with a superior experience in the resolution of varied resolutions? With this doubt, I asked my daughter-in-law (front-end staff), and my daughter-in-law opened her eyes and asked me: what is adaptation? Fc and Nima do not seem to have such problems. Later, after careful questioning, she told me, oh, I set the size to 20% ~~ Root tracing is actually one reason. The web page provides a percentage calculation.

Similarly, after getting the design map provided by the UI, did you complain that Nima's logo is px? I used dp in the project. What is this? I explained it to the UI staff, the UI sister does not understand either. In this example, the conflicts between Android engineers and UI sisters can also be solved ~ The UI provides a fixed-size design draft, and you don't have to think about the layout when writing the layout. Without a brain to copy the pixel value of the above logo, you can achieve perfect adaptation. The ideal is not full ~~.

However, if Android provides the dp adaptation solution for different screens, what is the gap between dp and percentage?

2. dp vs percentage
  • Dp

Let's first take a look at the definition of dp:

Density-independent pixel (dp) independent pixel Density. The standard is 160dip. That is, 1dp corresponds to 1 pixel. The calculation formula is px = dp * (dpi/160). The larger the screen density, the more pixels corresponding to 1dp.
The above formula has a dpi. dpi is Dots Per Inch (the number of points printed Per Inch), that is, when the device DPI is 160, 1px = 1dp;

Well, the above concepts cannot be remembered. Just remember that dp is irrelevant to the pixel density. In actual use, 1dp is about 1/160 inch.

So what exactly does dp solve the adaptation problem? It can be seen that 1dp = 1/160 inch; then it can solve at least one problem, that is, you write a View in the layout file with a width and height of 160dp * 160dp, which is displayed on any resolution screen, the displayed size is approximately the same (may be inaccurate), which is approximately 1 inch * 1 inch.

However, this does not solve all adaptation problems:

  • There will still be differences in the presentation effect, just similar
  • When the physical size of the device is different, dp is powerless. The UI prepared for the 4.3-inch screen runs on the 5.0-inch screen, and there may be a lot of white space on the right and bottom. The 5.0-inch UI runs on a 4.3-inch device, which may not be displayed.

For more information, see link 1.

In a word, dp enables the same value to show roughly the same size at different resolutions. However, when the size of the device is significantly different, there is nothing to do with it. The adaptation problem still needs to be done by ourselves, so we may do this:

<?xml version="1.0" encoding="utf-8"?>  <resources>      <!-- values-hdpi 480X800 -->      <dimen name="imagewidth">120dip</dimen>      </resources>  <resources>      <!-- values-hdpi-1280x800 -->      <dimen name="imagewidth">220dip</dimen>      </resources>  <?xml version="1.0" encoding="utf-8"?>  <resources>      <!-- values-hdpi  480X320 -->      <dimen name="imagewidth">80dip</dimen>      </resources> 

The above code snippets come from the network. That is to say, for a high quality user experience, we still need to write multiple sets of data files for different dpi settings.

It can be seen that dp does not solve the adaptation problem. The following shows the percentage.

  • Percentage
    This concept does not need to be mentioned. For the width of controls supported on the web, you can refer to the width of the parent control to set the percentage. For the width of the outermost control, refer to the screen size to set the percentage. In fact, in Android devices, you only need to support the control to calculate the width and height by referring to the percentage of the screen.

For example, I have the following requirements:

  • For the Banner of the image display, in order to achieve this effect, I want to display the height on any mobile phone as 1/4 of the screen height.
  • My homepage is divided into two columns. I want the screen height of each topic to be 11/24 and the interval between them is 1/12.
  • The slidingmenu is 80% in width.

Of course, this is only from a large level, in fact, a small range of layout, the percentage may be more useful.

So the percentage is not supported now. To meet the above requirements, it may need 1. Code to perform dynamic computing (many people pass it directly, which is too troublesome); 2. weight (weight must rely on Linearlayout, and cannot be used in any scenario)

For another example, the height and width of a floating Button of mine should be 1/12 of the screen height, and the width of a Button of mine should be 1/3 of the screen width.

All the above requirements cannot be fulfilled by using dp. We hope that the widget size can be written in the following ways:

   <Button        android:text="@string/hello_world"        android:layout_width="20%w"        android:layout_height="10%h"/>

Use the ratio of width to height of the screen to define the width and height of the View.

Now we can see the difference between dp and percentage, and the percentage can better solve our adaptation problem.

  • Some tips adaptation

Let's take a look at some matching tips.

In fact, the above three tip points are used in the final analysis. match_parent is equivalent to 100% reference parent control; weight is allocated proportionally; custom view is nothing more than because most of the size is calculated by percentage;

Through these tips, we can see that if we can introduce the percentage mechanism in Android, we will be able to solve most adaptation problems. Next we will look at how to make Android support the concept of percentage.

3. Introduction of percentage 1. Introduction

In fact, our solution is to create a folder for the resolution of your desired mobile phone screen in the project.

For example:

Then, based on a benchmark, the reference means:

For example, the resolution of 480*320 is a benchmark.

  • The width is 320, divide the width of any resolution into 320 parts, the value is x1-x320
  • The height is 480, divide the height of any resolution into 480 parts, the value is y1-y480

For example, if the width of 800*480 is 480:

We can see that x1 = 480/reference = 480/320 = 1.5;

Other resolutions are similar ~~
You may ask, do we have to calculate these files and write them by ourselves? Don't be afraid.

So, you may have a question: What are the advantages of such writing?

Suppose I need to have a button in the center of the screen. The width and height are 1/2 of the screen width. How can I write a layout file?

<FrameLayout >    <Button        android:layout_gravity="center"        android:gravity="center"        android:text="@string/hello_world"        android:layout_width="@dimen/x160"        android:layout_height="@dimen/x160"/></FrameLayout>

We can see that our width and height are defined as x160, which is actually 50% of the width;
So:

We can see that the width and height of our buttons are always half the width of the screen, No matter what resolution model we use.

  • For design drawings

Assume that the current UI design is based on 480*320, and the above width and height of the logo are all px values, you can directly convert px to x [1-320], y [1-480], so that the layout can be adapted to the full resolution.

You may ask: What should I do if the resolution of the designer's design drawing is not fixed? Which will be discussed later ~

  • Some of the above mentioned dp cannot be implemented

You can try it by yourself after introducing the percentage ~~

Well, there is one major problem. We didn't say that there are so many resolutions. Nima, do we have to calculate it ourselves and then write it by hand?

2. Automatic Generation Tool

Well, in fact, this folder can also be written by hand, according to the resolution you need to support, and then write a set, which will be used in the future.

Of course, as a programmer, how can we do such a low job must be implemented by a program:

The following steps are required:

For mainstream resolutions, I have integrated them into our programs. For special resolutions, you can specify them through parameters. For screen resolution information, you can query through the site: http://screensiz.es/phone

The Code is as follows:

import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.PrintWriter;/** * Created by zhy on 15/5/3. */public class GenerateValueFiles {    private int baseW;    private int baseH;    private String dirStr = "./res";    private final static String WTemplate = "<dimen name=\"x{0}\">{1}px</dimen>\n";    private final static String HTemplate = "<dimen name=\"y{0}\">{1}px</dimen>\n";    /**     * {0}-HEIGHT     */    private final static String VALUE_TEMPLATE = "values-{0}x{1}";    private static final String SUPPORT_DIMESION = "320,480;480,800;480,854;540,960;600,1024;720,1184;720,1196;720,1280;768,1024;800,1280;1080,1812;1080,1920;1440,2560;";    private String supportStr = SUPPORT_DIMESION;    public GenerateValueFiles(int baseX, int baseY, String supportStr) {        this.baseW = baseX;        this.baseH = baseY;        this.supportStr += validateInput(supportStr);        System.out.println(supportStr);        File dir = new File(dirStr);        if (!dir.exists()) {            dir.mkdir();        }        System.out.println(dir.getAbsoluteFile());    }    /**     * @param supportStr     *            w,h;...w,h;     * @return     */    private String validateInput(String supportStr) {        StringBuffer sb = new StringBuffer();        String[] vals = supportStr.split(";");        int w = -1;        int h = -1;        String[] wh;        for (String val : vals) {            try {                if (val == null || val.length() == 0)                    continue;                wh = val.split(",");                w = Integer.parseInt(wh[0]);                h = Integer.parseInt(wh[1]);            } catch (NumberFormatException e) {                System.err.println("skip invalidate params : w,h = " + val);                continue;            }            sb.append(w + "," + h + ";");        }        return sb.toString();    }    public void generate() {        String[] vals = supportStr.split(";");        for (String val : vals) {            String[] wh = val.split(",");            generateXmlFile(Integer.parseInt(wh[0]), Integer.parseInt(wh[1]));        }    }    private void generateXmlFile(int w, int h) {        StringBuffer sbForWidth = new StringBuffer();        sbForWidth.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");        sbForWidth.append("<resources>");        float cellw = w*1.0f / baseW;        System.out.println(w + "," + baseW + "," + cellw);        for (int i = 1; i < baseW; i++) {            sbForWidth.append(WTemplate.replace("{0}", i + "").replace("{1}",                    change(cellw * i) + ""));        }        sbForWidth.append(WTemplate.replace("{0}", baseW + "").replace("{1}",                w + ""));        sbForWidth.append("</resources>");        StringBuffer sbForHeight = new StringBuffer();        sbForHeight.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");        sbForHeight.append("<resources>");        float cellh = h / baseH;        for (int i = 1; i < baseH; i++) {            sbForHeight.append(HTemplate.replace("{0}", i + "").replace("{1}",                    change(cellh * i) + ""));        }        sbForHeight.append(HTemplate.replace("{0}", baseH + "").replace("{1}",                h + ""));        sbForHeight.append("</resources>");        File fileDir = new File(dirStr + File.separator                + VALUE_TEMPLATE.replace("{0}", h + "")//                        .replace("{1}", w + ""));        fileDir.mkdir();        File layxFile = new File(fileDir.getAbsolutePath(), "lay_x.xml");        File layyFile = new File(fileDir.getAbsolutePath(), "lay_y.xml");        try {            PrintWriter pw = new PrintWriter(new FileOutputStream(layxFile));            pw.print(sbForWidth.toString());            pw.close();            pw = new PrintWriter(new FileOutputStream(layyFile));            pw.print(sbForHeight.toString());            pw.close();        } catch (FileNotFoundException e) {            e.printStackTrace();        }    }    public static float change(float a) {        int temp = (int) (a * 100);        return temp / 100f;    }    public static void main(String[] args) {        int baseW = 320;        int baseH = 400;        String addition = "";        try {            if (args.length >= 3) {                baseW = Integer.parseInt(args[0]);                baseH = Integer.parseInt(args[1]);                addition = args[2];            } else if (args.length >= 1) {                addition = args[0];            }        } catch (NumberFormatException e) {            System.err                    .println("right input params : java -jar xxx.jar width height w,h;w,h;...;w,h;");            e.printStackTrace();            System.exit(-1);        }        new GenerateValueFiles(baseW, baseH, addition).generate();    }}

At the same time, I provide a jar package. By default, double-click the package to generate it. usage instructions:

At the end of this article, we have built-in common resolutions. The Default Benchmark is 480*320. For special requirements, you can specify the benchmark through the command line:

For example, the reference size is 1280*800, and the extra size is 1152*735; the value is 4500*3200;

Follow

Java-jar xx. jar width height width, height_width, height

The above format is enough.

At this point, we have compiled a tool to generate all the values files that need to adapt to resolution based on a certain reference size, so that when writing layout files, we can refer to the screen resolution; the design drawing provided by the UI allows you to quickly write the layout according to the pixel units identified by the UI. Basically solved the adaptation problem.

Some companies have put this solution into use. I personally think it is quite good. If you have a better solution to solve the problem of screen adaptation, please leave a message to discuss or directly post a link to the article, you can share your experience so that our team can grow ~~.

Note: The idea of this solution comes from [blue-Shenzhen] in the group of Android Day Up. With its consent, the above program also draws on the source code shared by it. Thank you for your identification and wish you a successful start!

OK ~

Group number: 264950424. Welcome to the group.

Public Account: hongyangAndroid
(Please pay attention to it and push blog information as soon as possible)

Reference

Learning notes for Android multi-screen adaptation

Sharing of open-source, original, and practical Android screen adaptation solutions

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.