Android ImageView 图像视图

本章节我们来学习下 ImageView 缩放相关的知识,和实现自定义 ImageView 实现一个圆形图片效果 (各种圆形头像)

android:adjustViewBounds 设置缩放是否保持长宽比

android:adjustViewBounds 属性用于设置缩放时是否保持原图长宽比

单独设置不起作用,需要配合 maxWidthmaxHeight 属性一起使用

而后面这两个属性也是需要 android:adjustViewBounds 为 true 才会生效

对,三者就是这种共生关系

属性 说明
android:adjustViewBounds 设置缩放时是否保持原图长宽比
android:maxHeight 设置 ImageView 的最大高度
android:maxWidth 设置 ImageView 的最大宽度

我们写一个范例来演示不设置三个属性和设置三个属性的差别

  1. 创建一个 空的 Android 项目 cn.twle.android.ImageView

  2. 下载 /static/i/meimei_160x360.jpg 并放到 res/drawable 目录下,重命名为 meimei.jpg

  3. 修改 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的部分作裁剪处理

我们写一个范例来演示下上面的各种值的情况

  1. 创建一个 空的 Android 项目 cn.twle.android.ImageView

  2. 下载 /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 上的相关开源实现

  1. RoundedImageView
  2. CircleImageView

  1. 创建一个 空的 Android 项目 cn.twle.android.ImageView

  2. 下载 /static/i/meimei.jpg 并放到 res/drawable 目录下

  3. 自定义 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();
        }
    }
    
  4. 修改布局文件 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>
    
  5. 最后修改 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);
        }
    }
    

参考文档

  1. 官方API ImageView

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.