栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android图片底部对齐(scaleType底部对齐)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android图片底部对齐(scaleType底部对齐)

背景

今天在讨论UI优化的时候,首页有个控件支持动态切换背景图,但是该控件的高度并不固定,如果直接使用图片背景的话会照成图片失真,如下图(子控件显示条数不固定)

这时候ui妹子突然说图片由下往上展示,上面超出部分就不显示了 iOS妹子和小程序小伙异口同声说“没问题”,但是又不能说Android搞不了,只能笑着说没问题(MMP),然后就开始研究起方案。

尝试方案一(失败)(scaleType)

第一个尝试方案肯定是scaleType了,记得有个fitEnd的属性平时用的少,然后发现并不符合预期,全部效果如下

尝试方案二(失败)-自定义Glide的Transform

思路:自定义Transform,等Glide下载完图片的时候回调transform接口,通过修改Bitmap的RectF区域来进行显示部分图片,然后scaleType用fitXY,代码如下

@Override
protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
    return Crop(pool, toTransform);
}

private Bitmap Crop(BitmapPool pool, Bitmap toTransform) {
    if (toTransform == null) {
        return null;
    }
    int bpWidth = toTransform.getWidth();
    int bpHeight = toTransform.getHeight();
    float bpRatio = (bpWidth * 1f) / bpHeight;
    Bitmap result = pool.get(toTransform.getWidth(), toTransform.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(result);
    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setShader(new BitmapShader(toTransform, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
    RectF rectF;
    if (targetRatio > bpRatio) {
        float top = (bpWidth * height * 1f / width);
        rectF = new RectF(0f, top, bpWidth, bpHeight);
    } else {
        rectF = new RectF(0f, 0f, bpWidth, bpHeight);
    }
    canvas.drawRect(rectF, paint);
    return result;
}

但通过实际发现,设置成scaleType:fitXY ,这样实际操作还会存在图片失真的情况,且裁剪的区域是已经显示在imageView上面的图片,还要考虑缩放等问题,到这里久放弃了。

尝试方案三(有效)-自定义View修改Matrix

思路:因为图片的宽度会比View的宽度宽或者窄,所以要考虑缩放,然后把缩放后的图片平移到控件底部,这时候想到的是修改Canvas的Matrix。

相关代码 xml(scaleType设置为matrix,不要问为什么,问就是比较好处理)
    
java代码也比较简单
public class MatrixBottomImageView extends androidx.appcompat.widget.AppCompatImageView {
    
    private int width, height;
    
    private Matrix matrix;

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

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

    public MatrixBottomImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (width != w || height != h) {//宽高改变时需刷新值
            width = w;
            height = h;
        }
    }

    private void init() {
        matrix = new Matrix();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Drawable drawable = getDrawable();
        if (drawable != null) {
            int intrinsicWidth = drawable.getIntrinsicWidth();//获取图片宽度
            int intrinsicHeight = drawable.getIntrinsicHeight();//获取图片高度
            matrix.reset();
            float sx = width * 1f / intrinsicWidth;//求出缩放比例
            matrix.postScale(sx, sx, 0, 0);//以左上角为原点,进行缩放
            intrinsicHeight = (int) (intrinsicHeight * sx);//求出缩放后的图片高度
            int dy = -intrinsicHeight + height;//实际的偏移量(往上移需要为负数)
            matrix.postTranslate(0, dy);//进行平移
            canvas.setMatrix(matrix);//设置画布矩阵
        }
        super.onDraw(canvas);
    }
}

实际效果如下:

总结:

问题的难度不高,但可以锻炼解决问题思路,还是要多点动手才行,今天也是搬砖的一天 要元气满满哦。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/572173.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号