Android drawable detail

We all know that in the Android project which, drawable folders are used to place picture resources, whether it is jpg, png, or 9.png, can be placed here. In addition, there are xml files like the selector can also be placed under the drawable folder.

But if you are using Android Studio to create a new project, you will find the following directory structure:

20160422203208418.png

Ok? How will there be so many mipmap at the beginning of the folder, and their naming rules and drawable folder is very similar, but also hdpi, mdpi, xhdpi, etc., and which really is put the picture, is the Android project placed in the picture location has been changed?

Developers who have just switched from Eclipse to Android Studio may be unfamiliar with the mipmap folder. In fact, there is no need to worry that our usual programming habits do not need to be changed because the mipmap folder is only used to place the application’s icon’s.

Then before we all put the icon of the application and the ordinary picture resources together into the drawable folder, so it will look more messy, and sometimes want to find a picture from a bunch of picture resources within half a day Can not find, and more than one file is also prone to leakage of the situation, but just Android is extremely recommended that we in each resolution folder below put a corresponding size of the icon, so they are independent Put mimap folder which is a good solution to this problem.

In addition, the icon placed in the mipmap folder can also let our program launcher icon automatically have the ability to display across the device density, for example, a screen density is xxhdpi device can automatically load mipmap-xxxhdpi icon as an application Launcher icon, so the icon will look more delicate.

In addition, for each density of the icon should be designed into what size In fact, Android is also given the best advice, icon size is best not to design, because too low resolution will cause the icon is blurred, and too high The resolution will only increase the size of APK. The recommended dimensions are shown in the following table:

density Recommended size
mipmap-mdpi 48 * 48
mipmap-hdpi 72 * 72
mipmap-xhdpi 96 * 96
mipmap-xxhdpi 144 * 144
mipmap-xxxhdpi 192 * 192

Then we refer to the mipmap method and the way before the drawable is exactly the same, in the resource to use @ mipmap / res_id, in the code to use R.mipmap.res_id. For example, AndroidManifest.xml is like this reference ic_launcher icon:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
</application>

Then let’s introduce some of the drawable techniques you do not know: First I prepared a picture of 270 * 480 pixels: 20160424154510643.png Name the image android_logo.png and place it under the drawable-xxhdpi folder. Why should I put it in this folder? Because the density of my mobile phone screen is xxhdpi. So how can you know the density of your own mobile phone screen? You can use the following method to get the value of the screen to the value:

float xdpi = getResources().getDisplayMetrics().xdpi;
float ydpi = getResources().getDisplayMetrics().ydpi;

Where xdpi represents the value of the screen width, ydpi represents the screen height of the dpi value, usually these two values are almost equal or very close to the two values on my phone are about 403. What does 403 mean? We directly refer to the following table to know:

dpi range density
0dpi ~ 120dpi ldpi
120dpi ~ 160dpi mdpi
160dpi ~ 240dpi hdpi
240dpi ~ 320dpi xhdpi
320dpi ~ 480dpi xxhdpi
480dpi ~ 640dpi xxxhdpi

From the table can be seen, 403dpi is between 320dpi to 480dpi, so belong to the scope of xxhdpi.
After the picture is gone, I quote this picture in the layout file as follows:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   >

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/android_logo"
        />

</LinearLayout>

In the ImageView control to specify the load android_logo this map, and the ImageView control are set to wrap_content width, so how much the picture, how much of our control will be. Now run the program, the effect is as follows: 20160423155934999.png Because my mobile phone resolution is 1080 * 1920 pixels, and this picture resolution is 270 * 480 pixels, just a quarter of the resolution of the phone, so from the figure can also be seen, android_logo picture The width and height are probably occupied by the screen width of about a quarter, the size of the basic is more accurate. So far everything is fine, is not it? Here we try to make some changes, android_logo.png this map moved to the drawable-xhdpi folder, not to copy a copy to the drawable-xhdpi folder, but the picture moved to the drawable-xhdpi folder, and then Re-run the program, the effect as shown below:

20160423160735251.png

Ok? How do you feel like the picture becomes bigger, is it ill Then we will move this picture to the drawable-mdpi folder try, re-run the program, the effect as shown below:

20160423161009361.png

This is certainly not the illusion, it is too obvious, the picture was enlarged! So why is a good end of the picture will be automatically zoom? And this magnification is not a bit too much. In fact, Android does these scaling operations have its strict rules and algorithms. There may be a lot of friends do not for many years Android did not pay attention to the rules of these zoom, because these details are too small, then this micro-skills to explore inside, we come to these details reasonable. First explain why the picture will be enlarged, when we use the resource id to refer to a picture, Android will use some rules to help us match the most suitable picture. What is the most suitable picture? For example, my mobile phone screen density is xxhdpi, then drawable-xxhdpi folder under the picture is the most suitable picture. So when I quote this image with android_logo, if the drawable-xxhdpi folder has this picture, it will be used first, in which case the picture will not be scaled. However, if the drawable-xxhdpi folder does not have this picture, the system will automatically go to other folders to find this map, and priority to the higher density of the folder to find this picture, our current scene is Drawable-xxxhdpi folder, and then found here android_logo this map, then try to find a higher density of the folder and found no higher density, and this time will go to the drawable-nodpi folder to find this picture , And found no, then it will go to the lower density of the folder to find, followed by drawable-xhdpi -> drawable-hdpi -> drawable-mdpi -> drawable-ldpi. The general match rule is the case, then for example, now finally in the drawable-mdpi folder to find android_logo this map, but the system will think that you this picture is designed specifically for low-density devices designed, if the direct map In the current high-density devices on the use of pixels may be too low, so the system automatically help us to do such an amplification operation. Then the same reason, if the system is in the drawable-xxxhdpi folder below to find this picture, it will think that this picture is designed for higher density devices, if the map directly on the current use of the device There may be pixels too high, so will automatically help us to do a shrinking operation. So, we can try to move the android_logo map to the drawable-xxxhdpi folder below to get this result:

20160423172553614.png

You can see, now the picture width and height are not up to a quarter of the phone screen, indicating that the picture is really reduced. In addition, just introduced the rules when the mention of a drawable-nodpi folder, this folder is a density-free folder, where the picture system will not automatically scale it, the original picture is how much will be the actual Show how much. But should pay attention to the order of a load, drawable-nodpi folder is in the matching density folder and higher density folder can not find the case will go here to find pictures, so placed in the drawable-nodpi folder Pictures are usually not recommended to put other folders inside the folder. The picture is the reason for the amplification Now we have figured out, then there is a question that is how to enlarge the magnification is how to determine it? Unfortunately, I did not find the relevant documentation, but I summed up a law, here to share with you. Or just look at the range of dpi – density table:

dpi density
0dpi ~ 120dpi ldpi
120dpi ~ 160dpi mdpi
160dpi ~ 240dpi hdpi
240dpi ~ 320dpi xhdpi
320dpi ~ 480dpi xxhdpi
480dpi ~ 640dpi xxxhdpi

It can be seen that the dpi of each density has a maximum value, and the ratio between the maximum is the proportion of the picture that will be automatically enlarged by the system. I said that we have to verify through the example, modify the layout of the document code, as follows:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   >

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/android_logo"
        />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="获取图片宽高"
        android:onClick="buttonClick"
        />

</LinearLayout>

You can see that we have added a button and registered a click event for the button. And then deal with this click event in MainActivity:

public class MainActivity extends AppCompatActivity {

    ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView) findViewById(R.id.image);
    }


    public void buttonClick(View view) {
        Toast.makeText(this, "width:" + imageView.getWidth(), Toast.LENGTH_SHORT).show();
        Toast.makeText(this, "height:" + imageView.getHeight(), Toast.LENGTH_SHORT).show();
    }
}

Here in the click event, respectively, to obtain the picture width and height and use Toast prompted out. The code can be modified so much, and then move the picture to the drawable-mdpi folder.

Here we begin to analyze, mdpi density of the highest dpi value is 160, and xxhdpi density of the highest dpi value is 480, so it is a 3 times the relationship, then we can guess, put the drawable-mdpi folder under the picture Xxhdpi density display on the device will be enlarged 3 times. Corresponding to android_logo this picture, the original pixel is 270 * 480, 3 times after amplification should be 810 * 1440 pixels. Run the program below, the effect is as follows:

20160423175803621.gif

Verification passed. Let’s try again and move the image to the drawable-xxxhdpi directory. Xxxhdpi density of the highest dpi value is 640,480 is its 0.75 times, then we can guess, put the drawable-xxxdpi folder under the image in the xxhdpi density device display will be reduced to 0.75 times. 270 * 480 0.75 times should be 202.5 * 360, because the pixels do not support the decimal point, then rounding should be 203 * 360 pixels. Re-run the program, the effect as shown below:

20160423180631696

Re-pass through. If you are interested, you can use several other types of dpi drawable folder to try, should be suitable for this set of zoom rules. So that we put the picture why will be scaled, as well as the specific zoom times are clear, drawable related details you have to explore the very subtle.

But this article is not finished here, the following I am going to talk about our actual development which will encounter the scene. According to the development of Android recommendations, we prepare the picture resources as much as possible to each density of equipment should be prepared a set, so that the program can be the best fit. But the reality is that the company’s UI are usually only to a set of picture resources, want them for each density of equipment design a set of picture resources, and still in accordance with the scale of the rules we have to design, Think too happy. Yes, this is the reality, then in this case, we should only have this set of picture resources on which the density of the folder under it?

Can be analyzed in this way, according to what we have just learned, if a picture on the low density folder, then the high-density devices will be automatically displayed when the picture is enlarged, and if a picture on the high Density folder, then the low-density devices will be automatically displayed when the picture is reduced. Then we can assess the way through the cost of a picture was reduced after the show is actually no side effects, but a picture is enlarged after the show means to take up more memory. Because the picture is enlarged, the pixels will become more, and each pixel is to take up memory.

We can still intuitively through the example to experience, first android_logo.png picture moved to the drawable-xxhdpi directory, run the program after we through the Android Monitor to observe the program memory usage:

20160423221840743.png

You can see that the program takes up about 19.45M of memory. And then move the android_logo.png picture to the drawable-mdpi directory, rerun the program, the results as shown below:

20160423222108212.png

Now rose to 23.40M, and occupied a significant increase in memory. If you move the picture to the drawable-ldpi directory, you will find that taking up memory will be higher.

This example also verifies a problem, I believe that there are a lot of more experienced Android programmers may have encountered this situation, that is, when your project becomes more and more, sometimes loaded a drawable- Hdpi under the picture, the program directly OOM collapse, but if this map into the drawable-xhdpi or drawable-xxhdpi will not collapse under the fact that this is the truth.
Then after a series of the above analysis, the answer will naturally come out, the picture resources should be placed in the high-density folder, so you can save the picture memory costs, and UI in the design of the picture should also try to face high-density screen Equipment to design. For now, the best place to put the picture resources folder is drawable-xxhdpi. Then some friends may ask, is not there a higher density of drawable-xxxhdpi? Why not put it here? This is because the market 480dpi to 640dpi device is too small, if the screen for this level of density to design pictures, the picture is not in the case of scaling itself has been great, and basically can not save memory The role of expenditure.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s