Android ImageView 图像视图
本章节我们来学习下 ImageView 缩放相关的知识,和实现自定义 ImageView 实现一个圆形图片效果 (各种圆形头像)
android:adjustViewBounds 设置缩放是否保持长宽比
android:adjustViewBounds
属性用于设置缩放时是否保持原图长宽比
单独设置不起作用,需要配合 maxWidth 和 maxHeight 属性一起使用
而后面这两个属性也是需要 android:adjustViewBounds
为 true 才会生效
对,三者就是这种共生关系
属性 | 说明 |
---|---|
android:adjustViewBounds | 设置缩放时是否保持原图长宽比 |
android:maxHeight | 设置 ImageView 的最大高度 |
android:maxWidth | 设置 ImageView 的最大宽度 |
我们写一个范例来演示不设置三个属性和设置三个属性的差别
-
创建一个 空的 Android 项目
cn.twle.android.ImageView
-
下载 /static/i/meimei_160x360.jpg 并放到
res/drawable
目录下,重命名为meimei.jpg
-
修改
activity_main.xml
添加几个<ImageView>
<?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" android:orientation="vertical" > <!-- 正常的图片 --> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="5px" android:src="@drawable/meimei" /> <!-- 限制了最大宽度与高度,并且设置了调整边界来保持所显示图像的长宽比--> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="5px" android:adjustViewBounds="true" android:maxHeight="64dp" android:maxWidth="64dp" android:src="@drawable/meimei" /> </LinearLayout>
运行 demo 效果如下
我们可以看到,最下面的那个因为通过 maxWidth 和 maxHeight 限制 ImageView 最大宽度与高度为 64dp,就是最多只能显示 64x64 的图片,又设置了一个 adjustViewBounds = "true" 调整我们的边界来保持图片的长宽比
android:scaleType 设置缩放类型
android:scaleType
用于设置显示的图片如何缩放或者移动以适应 ImageView 的大小
Java代码可以通过 imageView.setScaleType(ImageView.ScaleType.CENTER);
来设置
可选值如下
值 | 说明 |
---|---|
fitXY | 对图像的横向与纵向进行独立缩放,使得该图片完全适应ImageView,但是图片的横纵比可能会发生改变 |
fitStart | 保持纵横比缩放图片,知道较长的边与Image的编程相等,缩放完成后将图片放在ImageView的左上角 |
fitCenter | 同上,缩放后放于中间 |
fitEnd | 同上,缩放后放于右下角 |
center | 保持原图的大小,显示在ImageView的中心。当原图的size大于ImageView的size,超过部分裁剪处理。 |
centerCrop | 保持横纵比缩放图片,知道完全覆盖ImageView,可能会出现图片的显示不完全 |
centerInside | 保持横纵比缩放图片,直到ImageView能够完全地显示图片 |
matrix | 默认值,不改变原图的大小,从ImageView的左上角开始绘制原图,原图超过ImageView的部分作裁剪处理 |
我们写一个范例来演示下上面的各种值的情况
-
创建一个 空的 Android 项目
cn.twle.android.ImageView
-
下载 /static/i/meimei.jpg 并放到
res/drawable
目录下
fitEnd,fitStart,fitCenter
值 | 说明 |
---|---|
fitStart | 保持纵横比缩放图片,知道较长的边与Image的编程相等,缩放完成后将图片放在ImageView的左上角 |
fitCenter | 同上,缩放后放于中间 |
fitEnd | 同上,缩放后放于右下角 |
修改 activity_main.xml
添加几个 <ImageView>
<?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" android:orientation="vertical" > <ImageView android:layout_width="128dp" android:layout_height="128dp" android:layout_margin="5px" android:scaleType="fitStart" android:src="@drawable/meimei" /> <ImageView android:layout_width="128dp" android:layout_height="128dp" android:layout_margin="5px" android:scaleType="fitCenter" android:src="@drawable/meimei" /> <ImageView android:layout_width="128dp" android:layout_height="128dp" android:layout_margin="5px" android:scaleType="fitEnd" android:src="@drawable/meimei" /> </LinearLayout>
运行结果如下
centerCrop 与 centerInside
值 | 说明 |
---|---|
centerCrop | 按横纵比缩放,直接完全覆盖整个 ImageView |
centerInside | 按横纵比缩放,使得 ImageView 能够完全显示这个图片 |
修改 activity_main.xml
添加几个 <ImageView>
<?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" android:orientation="vertical" > <ImageView android:layout_width="128dp" android:layout_height="128dp" android:layout_margin="5px" android:scaleType="centerCrop" android:src="@drawable/meimei" /> <ImageView android:layout_width="128dp" android:layout_height="128dp" android:layout_margin="5px" android:scaleType="centerInside" android:src="@drawable/meimei" /> </LinearLayout>
运行结果如下
fitXY
不按比例缩放图片,目标是把图片塞满整个 View
修改 activity_main.xml
添加几个 <ImageView>
<?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" android:orientation="vertical" > <ImageView android:layout_width="128dp" android:layout_height="128dp" android:layout_margin="5px" android:scaleType="fitXY" android:src="@drawable/meimei" /> </LinearLayout>
运行结果如下
matrix
ImageView 的左上角开始绘制原图,原图超过 ImageView 的部分作裁剪处理
修改 activity_main.xml
添加几个 <ImageView>
<?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" android:orientation="vertical" > <ImageView android:layout_width="128dp" android:layout_height="128dp" android:layout_margin="5px" android:scaleType="matrix" android:src="@drawable/meimei" /> </LinearLayout>
运行结果如下
center
保持原图的大小,显示在 ImageView 的中心
当原图的 size 大于 ImageView 的 size,超过部分裁剪处理
修改 activity_main.xml
添加几个 <ImageView>
<?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" android:orientation="vertical" > <ImageView android:layout_width="128dp" android:layout_height="128dp" android:layout_margin="5px" android:scaleType="center" android:src="@drawable/meimei" /> </LinearLayout>
运行结果如下
圆形的 ImageView
我们可以在很多 APP 上看到圆形或者圆角的图像,比如微博的头像
这些圆形的图像几乎都是用 ImageView 做一些简单的配置实现的
当然了,我们这里只是简单的实现,没有抗锯齿等,如果要用在项目中,可以看 GitHub 上的相关开源实现
-
创建一个 空的 Android 项目
cn.twle.android.ImageView
-
下载 /static/i/meimei.jpg 并放到
res/drawable
目录下 -
自定义
RoundImageView
继承自ImageView
RoundImageView.java
package cn.twle.android.imageview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PaintFlagsDrawFilter; import android.graphics.Path; import android.graphics.Rect; import android.graphics.Region; import android.util.AttributeSet; import android.widget.ImageView; public class RoundImageView extends ImageView { private Bitmap mBitmap; private Rect mRect = new Rect(); private PaintFlagsDrawFilter pdf = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG); private Paint mPaint = new Paint(); private Path mPath=new Path(); public RoundImageView(Context context, AttributeSet attrs) { super(context, attrs); init(); } //传入一个Bitmap对象 public void setBitmap(Bitmap bitmap) { this.mBitmap = bitmap; } private void init() { mPaint.setStyle(Paint.Style.STROKE); mPaint.setFlags(Paint.ANTI_ALIAS_FLAG); mPaint.setAntiAlias(true);// 抗锯尺 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if(mBitmap == null) { return; } mRect.set(0,0,getWidth(),getHeight()); canvas.save(); canvas.setDrawFilter(pdf); mPath.addCircle(getWidth() / 2, getWidth() / 2, getHeight() / 2, Path.Direction.CCW); canvas.clipPath(mPath, Region.Op.REPLACE); canvas.drawBitmap(mBitmap, null, mRect, mPaint); canvas.restore(); } }
-
修改布局文件 activity_main.xml 添加 RoundImageView
<?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" android:orientation="vertical" > <cn.twle.android.imageview.RoundImageView android:id="@+id/img_round" android:layout_width="128dp" android:layout_height="128dp" android:layout_margin="5px"/> </LinearLayout>
-
最后修改 MainActivity.java
package cn.twle.android.imageview; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { private RoundImageView img_round; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); img_round = (RoundImageView) findViewById(R.id.img_round); Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.meimei); img_round.setBitmap(bitmap); } }
参考文档
- 官方API ImageView