Android资源文件夹图片的适配分析

Android设备上,我们一般适配图片的常用方案,都基本是在较大分辨率的条件下准备一张较大的图片。比如设计图是1920*1080下的100*100的图片,我们一般可以在xxhdpi,xhdpi,hdpi,mdpi屏幕密度下的mipmap下放入300*300,200*200,150*150,100*100的图片。通常我们一般都是选取较大的的那个密度下的图片(也就是xxhdpi下的300*300这张图片)。这样不管是小分辨率,还是任意屏幕密度下的Android设备,只要ImageView宽度,高度都不大于100px,图片一般都不会失真。不过有些情况,限制不了控件大小的时候,可能会放大到失真(缩小不考虑)(比如一些自定义控件属性或者drawble文件下的某些xml自定义图案的时候引用图片有可能限制不了宽高)。


先上代码和图片






        

            

                

                
            
        


public class MainActivity extends AppCompatActivity {

    private ImageView iv;
    private TextView tv;
    private String strInfo = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        BitmapDrawable bitmapDrawable = (BitmapDrawable) iv.getDrawable();//layout 中获取图片信息
        final Bitmap bitmap = bitmapDrawable.getBitmap();
        final float density = getResources().getDisplayMetrics().density * 160;

        //java中获取图片信息
        BitmapDrawable drawable = (BitmapDrawable) getResources().getDrawable(R.mipmap.test960_540);
        final Bitmap bitmap2 = drawable.getBitmap();

        iv.post(new Runnable() {
            @Override
            public void run() {
                strInfo += "屏幕像素密度=" + density + "dpi\n";

                strInfo += "图片:width=" + bitmap.getWidth() + "px\n";
                strInfo += "图片:height=" + bitmap.getHeight() + "px\n";

                strInfo += "图片1:width=" + bitmap2.getWidth() + "px\n";
                strInfo += "图片1:height=" + bitmap2.getHeight() + "px\n";
                strInfo += "iv:width=" + iv.getWidth() + "px\n";
                strInfo += "iv:height=" + iv.getHeight() + "px\n";
                tv.setText(strInfo);
                tv.setTextSize(50 / getResources().getDisplayMetrics().density);
            }
        });


        //                 密度范围           比例
        //     ldpi      0dpi  -120dpi       0.75
        //     mdpi      120dpi-160dpi       1
        //     hdpi      160dpi-240dpi       1.5
        //     xhdpi     240dpi-320dpi       2
        //     xxhdpi    320dpi-480dpi       3
        //     xxxhdpi   480dpi-640dpi       4
    }

    private void initView() {
        iv = (ImageView) findViewById(R.id.iv);
        tv = (TextView) findViewById(R.id.tv);
    }
}

资源目录

截图2.PNG

xxhdpi和mdp设备下的运行效果

截图1.PNG


最后再看图片在xxdpi文件下的情况

资源目录

截图4.PNG

xxhdpi和mdp设备下的运行效果

截图3_图片只在xxhdpi文件夹的情况.PNG

从代码和图片中可以看到,只是放了一张960*540的图片在mdpi情况下,ImageView宽高设置成自适应了。然后xxhdpi设备中不管是从layout中还是用java动态获取图片信息,发现bitmap大小都是960*540。mdpi的设备也是一样。
现在我们来分析一下,为什么会这样?
我们知道960*540的图片,我们放在了mdpi文件夹下,
第一种:在mdpi设备的环境下,设备会优先找mdpi下的图片(如果mdpi文件夹下没找到相应图片,会按顺序找xhdpi->xxhdpi->xxxhdpi,此时如果还没找到图片,会往下接着找ldpi以此类推找到这张图片),此时在mdpi中直接发现了这张图且和设备自身屏幕密度一样160dpi(mdpi),所以iv和bitmap不会进行放缩。此时读出的图片就是960*540的。
第二种:xxhdpi的设备中,我们也只能在mdpi中找到图片,此时由于设备密度大于资源文件下的密度,而且设备会认为我们已经做好图片的适配,所以直接给我们iv宽高各放大了3倍,但bitmap还是960*540。




从代码和图片中可以看到,只是放了一张960*540的图片在xxhdpi情况下,ImageView宽高设置成自适应了。然后mdpi设备中不管是从layout中还是用java动态获取图片信息,发现bitmap大小在小密度的设备(mdpi)中宽高各缩小了1/3。xxhdpi的设备读取都完全正常。
现在我们来分析一下,为什么会这样?
我们知道960*540的图片,我们放在了xxhdpi文件夹下,
第一种:在mdpi设备的环境下,设备在xxhdpi的文件夹下找到了图片,此时在xxhdpi中直接发现了这张图且和设备自身屏幕密度差了3倍(mdpi),所以bitmap会缩放1/3。此时读出的图片就是320*180。
第二种:xxhdpi的设备中,我们就不讨论了,因为对应自己资源文件夹下有图片就不会进行缩放。




总结

如果图片在低密度资源文件夹,在高密度设备上访问,iv如果设置成自适应,会自动放大。但是不管是在通过layout,还是直接java中直接访问这个图片文件,这个图片读出来的宽高还是真实大小。(记忆的话就当bitmap想放大,但不会超过自身真实宽高)。

如果图片在高密度资源文件夹,在低密度设备上访问,iv如果设置成自适应,会自动缩小(由于bitmap缩小导致)。而且不管是在通过layout,还是直接java中直接访问这个图片文件,这个图片读出来的宽高是缩小过后的。(记忆的话就当bitmap想缩小,且不会超过自身真实宽高)。

你可能感兴趣的:(Android资源文件夹图片的适配分析)