美文网首页
Android图片底部对齐(scaleType底部对齐)

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

作者: 木易杨yang | 来源:发表于2021-11-19 11:17 被阅读0次

    背景

    今天在讨论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,不要问为什么,问就是比较好处理)
        <com.study.MatrixBottomImageView
            android:layout_width="200dp"
            android:layout_height="100dp"
            android:background="@android:color/holo_red_dark"
            android:scaleType="matrix"
            android:src="@drawable/icon_dog_bg" />
    
    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);
        }
    }
    

    实际效果如下:


    最终效果

    总结:

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

    相关文章

      网友评论

          本文标题:Android图片底部对齐(scaleType底部对齐)

          本文链接:https://www.haomeiwen.com/subject/thbstrtx.html