目录
结果总览
全篇为个人理解终结,如有出入请参考官方文档
ImageVIew 按比例拉伸图片,前提是不想让ImageView控件自身的大小受影响。
网上找到的基本在说scaleType 类型,还有android:adjustViewBounds ,最后发现简直乱七八糟各种属性都不按照期望来,甚至还有要重写onMeasure方法的,作为一个只是想写一个界面的我凌乱了,结合各种尝试和sdk提示信息后,汇总一下个人的理解
结论:保持图片宽高比总体有两种思路:
一: 图片适应控件。让图片缩放,来适应控件大小。通过修改图片的缩放方式以及配合背景图
二: 控件适应图片。让控件大小自适应,来适应图片。保持和图片一样的宽高比,来适应图片。
实践示例
不需要重新什么方法,只需要修改布局文件,以下示例用的第一种思想,图片来适应控件,如果两个方式都混着用,属性都在修改,就会感觉混乱,效果总是和文档描述的不一样,让人凌乱。
我的目的是一个界面放了上下两个图片的控件,控件上下平分总界面的大小,图片的大小尺寸可以任意。在保持这两个控件大小的前提下,让控件的图片保持等宽高。只通过xml布局来实现
最终源代码即效果:
背景是一个纯色的白图,不够填充的部分就会漏出背景图,但是背景是白的所以看起来融为一体
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/client"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@drawable/start_bg2"
android:scaleType="centerInside"
android:src="@drawable/client" />
<ImageView
android:id="@+id/server"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@drawable/start_bg2"
android:scaleType="centerInside"
android:src="@drawable/server" />
</LinearLayout>
效果图:
横屏:
原理说明:
我们要的是修改控件图片的填充和scale(缩放方式),而不是动控件的尺寸,所以ImageView控件的layout_width 和layout_height 不要动它,即按照 宽 match_parent 占满父控件,高度填0,则高度会按照weight权重来自动分配。 scaleType 顾名思义就是缩放类型,AS 中的提示文档:
Formats: enum Values: center, centerCrop, centerInside, fitCenter, fitEnd, fitStart, fitXY, matrix Controls how the image should be resized or moved to match the size of this ImageView. See {@link android.widget.ImageView.ScaleType}
关于这几种方式的效果,很简单,试一下就可以直接看到效果了。 AS上鼠标放上去也有提示
- center: Center the image in the view, but perform no scaling 不缩放居中。图片事多大就多大,多了我也放不小,少了就漏出控件背景色
- centerCrop:Scale the image uniformly (maintain the image's aspect ratio) so both dimensions (width and height) of the image will be equal to or larger than the corresponding dimension of the view (minus padding). The image is then centered in the view. 均匀缩放图像(保持图像的纵横比),使图像的两个维度(宽度和高度)等于或大于视图的相应维度(减去填充)。然后图像在视图中居中。 简单说:保持宽高比缩放,但是缩小放大后图片的宽和高都会大于或等于控件的宽高,即按照宽和高中比较小的一个边来对齐控件,这种缩放肯定会发生裁剪。 所以也叫Crop
- centerInside:Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or less than the corresponding dimension of the view (minus padding). The image is then centered in the view. 均匀缩放图像(保持图像的纵横比),使图像的两个维度(宽度和高度)等于或小于视图的相应维度(减去填充)。然后图像在视图中居中 简单说:保持宽高比缩放,但是缩小放大后图片的宽和高都会小于或等于控件的宽高,即按照宽高比中比较大的一个边来对齐控件,这种缩放刚好能把整个图放进来。所以叫insider ,和centerCrop刚好相反
- 原则上上面三中方式已经包括了所以缩放方式,后续的fitXXX , AS上也没有提示注释, 应该只是写扩充,后续有发现再补充吧。。。
补充说明:
- android:background 这个是背景,我们设置src 图片,并且把图片进行等比缩放,如果有剩余的空间没有填满,就会漏出背景,这个背景就在这里设置,用一个纯色的看不错缩放痕迹的图片上去就行。
- android:adjustViewBounds :
Formats: boolean Set this to true if you want the ImageView to adjust its bounds to preserve the aspect ratio of its drawable 如果希望ImageView调整其边界以保持其可绘制视图的纵横比,请将此设置为true。 这个是让ImageVIew控件自身的大小发生变化,通常让layout_width或layout_height 为wrapcontent, 然控件来适应图片的比例,和我们的这个前提就相违背,它不是通过保持图片缩放宽高比,而是保持控件适应图片的宽高比。 所以经常用上这个属性需要配合maxWidth、MaxHeight一起使用,因为,要给控件自适应大小一个范围限制。
再次汇总
所以保持图片宽高比总体有两种思路:
一: 让图片缩放,来适应控件大小。通过修改图片的缩放方式以及配合背景图
二: 让控件大小自适应,保持和图片一样的宽高比,来适应图片。
不要混着用, 同时修改android:adjustViewBounds 和android:scaleType 简直凌乱