zz android studio里的drawable问题
drawable/
For bitmap files (PNG, JPEG, or GIF), 9-Patch image files, and XML files that describe Drawable shapes or Drawable objects that contain multiple states (normal, pressed, or focused). See the Drawable resource type.
mipmap/
For app launcher icons. The Android system retains the resources in this folder (and density-specific folders such as mipmap-xxxhdpi) regardless of the screen resolution of the device where your app is installed. This behavior allows launcher apps to pick the best resolution icon for your app to display on the home screen. For more information about using the mipmap folders, see Managing Launcher Icons as mipmap Resources.
hdpi里面主要放高分辨率的图片,如WVGA (480x800),FWVGA (480x854)
mdpi里面主要放中等分辨率的图片,如HVGA (320x480)
xhdpi里面主要放低分辨率的图片,如QVGA (720X1280)
xxhdpi里面主要放低分辨率的图片,如QVGA (1080x1920)
dpi是“dot per inch”的缩写,每英寸像素数。
四种密度分类: mdpi (medium), hdpi (high), xhdpi (extra high) and xxhdpi (Xextra high)
drawable-hdpi 对应DPI为240
drawable-mdpi 对应DPI为160
drawable-xhdpi 对应DPI为320
drawable-xxhdpi 对应DPI为480
获取屏幕DPI(屏幕密度)方法:
- DisplayMetrics dm = new DisplayMetrics();
- dm = getResources().getDisplayMetrics();
- float density = dm.density;//屏幕密度(像素比例:1.0, 1.5, 2.0,3.0)
- int densityDPI = dm.densityDpi;//屏幕密度(每寸像素:160, 240, 320, 480) --------------------
- ==================================================================================
4.0后,新建android工程,会自动生成drawable,drawalbe-ldpi,drawable-mdpi,drawable-hdpi,drawable-xhdpi,drawable-xxhdpi六个文件夹,除drawable外,其他5个文件夹对应四种级别的density:120dip(low),160dip(medium),240dip(high),320dip(xhigh),480dip(drawable-xxhdpi)。目前主流做法都是把图片文件放在drawable-hdpi文件夹内,和图片相关的xml文件(如按钮xml,用以在按钮点击时显示不同的背景图片效果)放在drawable文件夹内。
所谓density,是指屏幕上的像素密度,以160dip为标准密度。举例来说,当我们在布局文件layout.xml中放置一个View
<View android:layout_height="1dip" android:layout_width="100dip"/>
该View在密度为160dip的屏幕上显示的长度为100px(像素)长,而在320dip的屏幕上它的长度将为200px。
而当图片处于drawable文件夹内时,也需要做这种转换。假如在drawable-mdpi的文件夹内有一张22*44的图片,通过程序将其读入系统中时,假设屏幕密度为320dip,那它在内存中的大小将是44*88。
前面说过,目前主流做法是将图片放置在drawable-hdpi文件夹内,该文件夹对应的density是240dip,但其实现在的手机一般都是320dip甚至480dip了,所以放置在hdpi文件夹内的图片在显示时都是已经自动拉伸过了。
还有个问题,当直接读取sd卡或assert文件夹内的图片时,图片的大小是怎么样的呢?当我们读取sd卡内的图片时,我们首先获取的不是drawbale对象而是个bitmap对象,该bitmap对象的width和height对应的是图片的真实像素大小。而将bitmap对象转换为drawable时,除非我们手动设置了目标density,否则不进行缩放。
BitmapDrawable bmpDrawable = new BitmapDrawable(bitmap);
使用这个构造函数,默认的density是160,该构造函数已经被摒弃了,推荐使用下一个
BitmapDrawable bmpDrawable = new BitmapDrawable(getResources(),bitmap);
该构造函数会通过getResources获取到手机的density,将其设置为默认的density。
getResources().getDisplayMetrics().densityDpi
若我们需要进行缩放,可以通过下述方法设置目标density。
bmpDrawable.setTargetDensity(160)
在320dip长度的屏幕上,该bmpDrawable将会缩小为一半。
注:我原先以为 new BitmapDrawable(getResources(),bitmap)这个构造函数是为了将图片根据当前屏幕密度进行缩放。如屏幕密度为320dip时,在用了该构造函数后图片会自动放大1倍(Bitmap对象默认的density是160),但认真看了源码后发现,该方式是为了修改默认的density,即将160改为了320,之后再通过setTargetDensity方法设置真正需要缩放的密度。关于这点我实在想不到它的应用场景,感觉很不合理。