Android:带边框的,等比缩放的,铺满控件的ImageView

  • 上一篇已经完成一个不带边框的,等比缩放的,铺满控件的ImageView。但是需求往往是无止境的,可能你做好了一个,结果需求又有改变的增加。不过,不管怎么说,这个需求还是可以实现的。
  • 在上一篇中,我没有强调的是:在使用该自定义的ImageView的时候,一定不要在布局文件xml中设置如下属性:android:visibility="gone"。是的,就是一定不是使用gone属性。及时后面,你在的代码中将使用了imgview.setVisibility(View.VISIBLE);也是不行的。这个原因参照void android.view.ViewTreeObserver.OnGlobalLayoutListener.onGlobalLayout()方法的注释:
    • /**
      <ul><li>Callback method to be invoked when the global layout state or the visibility of views</li>
      <li>within the view tree changes
      */
    • 大致意思差不多就是:xxxxxx,算了,我就不翻译了,有需要的自行去找翻译软件吧。
  • OK,这个带边框的,铺满控件的,等比缩放的ImageView就是这样来写了:

  • 
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.graphics.drawable.Drawable;
    import android.util.AttributeSet;
    import android.view.ViewTreeObserver.OnGlobalLayoutListener;
    import android.widget.ImageView;
    
    /**
     * 带边框的,铺满控件的ImageView
     */
    @SuppressLint("DrawAllocation")
    public class BorderImageView extends ImageView implements
            OnGlobalLayoutListener {
    
        private static final int DEFAULT_FRAME_COLOR = 0x000;
        private static final boolean DEBUG = true;
        private int color = 0xff669900;
        private boolean once;
        private Matrix matrix;
    
        public BorderImageView(Context context) {
            this(context, null);
        }
    
        public BorderImageView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public BorderImageView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init();
        }
    
        private void init() {
            once = true;
            matrix = new Matrix();
            setScaleType(ScaleType.MATRIX);
        }
    
        @Override
        protected void onAttachedToWindow() {
            getViewTreeObserver().addOnGlobalLayoutListener(this);
            super.onAttachedToWindow();
        }
    
        @Override
        protected void onDetachedFromWindow() {
            getViewTreeObserver().removeOnGlobalLayoutListener(this);
            super.onDetachedFromWindow();
        }
    
        @SuppressLint("DrawAllocation")
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            // 画边框
            Rect rec = canvas.getClipBounds();
            rec.bottom--;
            rec.right--;
            Paint paint = new Paint();
            paint.setColor(color);
            paint.setStyle(Paint.Style.STROKE);
            canvas.drawRect(rec, paint);
        }
    
        @Override
        public void onGlobalLayout() {
            if (once) {
    
                // 1.view wh
                int width = getWidth();
                int height = getHeight();
                // 2. d dw dh
                Drawable drawable = getDrawable();
                if (drawable == null) {
                    return;
                }
                if (DEBUG) {
                    System.out.println("drawable:" + drawable);
                }
                int dw = drawable.getIntrinsicWidth();
                int dh = drawable.getIntrinsicHeight();
                // first trans
                float dx = width * 1.0f / 2 - dw * 1.0f / 2;
                float dy = height * 1.0f / 2 - dh * 1.0f / 2;
                matrix.postTranslate(dx, dy);
                // second scale
                float scale = 1.0f;
                if (dw > width && dh < height) {
                    scale = height * 1.0f / dh;// bigger
                }
                if (dw < width && dh > height) {
                    scale = width * 1.0f / dw;// bigger
                }
    
                if (dw < width && dh < height) {
                    float sh = height * 1.0f / dh;
                    float sw = width * 1.0f / dw;
                    scale = Math.max(sw, sh);
                    System.out.println("case3:"+sw+"--"+sh+"==="+scale);
                }
                if (dw > width && dh > height) {
                    float sw = width * 1.0f / dw;
                    float sh = height * 1.0f / dh;
                    scale = Math.max(sw, sh);
                    System.out.println("case4:"+sw+"--"+sh+"==="+scale);
                }
    
                if (DEBUG) {
                    System.out.println("scale:" + scale);
                }
                matrix.postScale(scale, scale, width / 2, height / 2);
                setImageMatrix(matrix);
                once = false;
            }
        }
    }
    • 额,代码不算很多,里面的东西其实都是之前有写过的。就不去解释了。
    • 然后在布局中去使用的话,就很简单了,比如:
    <com.xxxxx.yyyyyy.BorderImageView
            android:id="@+id/borderImg"
            android:layout_width="440dp"
            android:layout_height="440dp"
            android:padding="2dp"
            android:scaleType="matrix"
            android:src="@drawable/install"
            android:visibility="visible" />

    这里,我故意将宽高设置成一个固定的数字,是为了看到效果。当然,你设置成match_parent或者wrap_content也是OK的。对于很小的图片,这里的操作逻辑也是将它等比拉大。如果在使用中,感觉这样不好,也可以去修改一下上面的代码,或者给我留言,我到时候再发一个更能满足需求的控件出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值