ImageView

本文详细解析了 Android 中 ImageView 的 scaleType 和 adjustViewBounds 属性的功能及使用场景,并提供了自定义视图(如正方形和圆形图片视图)的具体实现方式。

简介

xxx

属性

android:scaleType
fitXY 
图不按比例扩大/缩小至View大小显
fitStart 
图按比例扩大/缩小至View宽,显在View上半部分位置
fitCenter 
图按比例扩大/缩小至View宽,居中显
fitEnd 
图按比例扩大/缩小至View宽,显在View下半部分位置
center 
图按原尺寸居中显示,长(宽)超过View长(宽)截图居中部分显
centerCrop 
图按比例扩大尺寸居中显,使图长(宽)等或大于View长(宽)
centerInside 
图内容完整居中显,尺寸过大按比例缩小原图尺寸使图长(宽)小或等于View长(宽)
android:adjustViewBounds
保原图长宽比,单设无用,配maxWidth或maxHeight用
Adjust the ImageView's bounds to preserve the aspect ration of its drawable.
调ImageView界限保图像宽高比不变
  • XML中android:adjustViewBounds="true"设ImageView之scaleType为fitCenter。但该fitCenter会被后面定义scaleType属性覆盖(前提已定义),除非Java再调setAdjustViewBounds(true)。
  • layout_width与layout_height都定值则adjustViewBounds无效。ImageView始终为设定宽高值。
  • layout_width与layout_height都wrap_content则adjustViewBounds无意义。ImageView始终同图宽高比而非同宽高值(通放大一些)。
  • 二者一定值,一wrap_content。如layout_width=“100px”,layout_height="wrap_content"时ImageView宽始终100px,高两况:
    • 图宽小100px时layout_height同图高(不缩放),完整显于ImageView中,ImageView高同图实高。图没占满ImageView(有空白)。
    • 图宽大等100px时ImageView同图宽高比,故ImageView的layout_height为100除以图宽高比。如图500X500则layout_height为100。图保宽高比缩放,完整显于ImageView且占满ImageView。

自定

方形

package module.whiteboard.view;

import android.content.Context;
import android.util.AttributeSet;

/**
 * @decs: An image view which always remains square with respect to its width.
 * @date: 2018/11/1 17:21
 */
class SquaredImageView extends android.support.v7.widget.AppCompatImageView {
    public SquaredImageView(Context context) {
        super(context);
    }

    public SquaredImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth());
    }
}

圆形

package widget.imageview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;

/**
 * Created on 2019/4/25.
 *
 * @author 郑少鹏
 * @desc 圆形图
 */
public class CircleImageView extends AppCompatImageView {
    private float width;
    private float height;
    private float radius;
    private Paint paint;
    private Matrix matrix;

    public CircleImageView(Context context) {
        this(context, null);
    }

    public CircleImageView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CircleImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        paint = new Paint();
        // 抗锯齿
        paint.setAntiAlias(true);
        // 初始缩放矩阵
        matrix = new Matrix();
    }

    /**
     * 测控件宽高并获其内切圆半径
     *
     * @param widthMeasureSpec  widthMeasureSpec
     * @param heightMeasureSpec heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = getMeasuredWidth();
        height = getMeasuredHeight();
        radius = Math.min(width, height) / 2;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Drawable drawable = getDrawable();
        if (drawable == null) {
            super.onDraw(canvas);
            return;
        }
        if (drawable instanceof BitmapDrawable) {
            // 设着色器给画笔
            paint.setShader(stepBitmapShader((BitmapDrawable) drawable));
            // 画圆
            canvas.drawCircle(width / 2, height / 2, radius, paint);
            return;
        }
        super.onDraw(canvas);
    }

    /**
     * 获ImageView资源图Bitmap
     * 利用Bitmap初始图着色器
     * 通缩放矩阵将原资源图缩放到铺满整绘制区
     * 避边界填充
     *
     * @param bitmapDrawable BitmapDrawable
     * @return BitmapShader
     */
    private BitmapShader stepBitmapShader(BitmapDrawable bitmapDrawable) {
        Bitmap bitmap = bitmapDrawable.getBitmap();
        BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        float scale = Math.max(width / bitmap.getWidth(), height / bitmap.getHeight());
        // 等比缩放图宽高(避拉伸)
        matrix.setScale(scale, scale);
        bitmapShader.setLocalMatrix(matrix);
        return bitmapShader;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

snpmyn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值