勾选框居右显示的AppCompatCheckBox

作者: blingbling_5a3f | 来源:发表于2019-12-16 22:46 被阅读0次

    1:需求

    如果要实现勾选框居右的AppCompatCheckBox怎么办。


    image.png

    肯定有人会说直接用TextView加一个选择器给DrawableRight不就可以了吗?但是这样有一点不足,就是没有AppCompatCheckBox状态变化的动画了。应该也有人会用一个LinearLayout包裹一个TextView和一个AppCompatCheckBox去实现,但是这样就会导致布局层级变深,布局里面的View的数量增加,布局加载速度变慢。

    2:实现过程

    1、AppCompatCheckBox是否拥有一个属性可以设置成这样的样式呢?带着这个问题我翻遍了AppCompatCheckBox可设置的属性,没有发现可以使勾选框居右的属性。
    2、查看AppCompatCheckBox的源码,看勾选框是怎么绘制的。发现勾选框的绘制是在CompoundButton里面完成的。

    @Override
        protected void onDraw(Canvas canvas) {
            final Drawable buttonDrawable = mButtonDrawable;
            if (buttonDrawable != null) {
                final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
                final int drawableHeight = buttonDrawable.getIntrinsicHeight();
                final int drawableWidth = buttonDrawable.getIntrinsicWidth();
    
                final int top;
                switch (verticalGravity) {
                    case Gravity.BOTTOM:
                        top = getHeight() - drawableHeight;
                        break;
                    case Gravity.CENTER_VERTICAL:
                        top = (getHeight() - drawableHeight) / 2;
                        break;
                    default:
                        top = 0;
                }
                final int bottom = top + drawableHeight;
                final int left = isLayoutRtl() ? getWidth() - drawableWidth : 0;
                final int right = isLayoutRtl() ? getWidth() : drawableWidth;
    
                buttonDrawable.setBounds(left, top, right, bottom);
    
                final Drawable background = getBackground();
                if (background != null) {
                    background.setHotspotBounds(left, top, right, bottom);
                }
            }
    
            super.onDraw(canvas);
    
            if (buttonDrawable != null) {
                final int scrollX = mScrollX;
                final int scrollY = mScrollY;
                if (scrollX == 0 && scrollY == 0) {
                    buttonDrawable.draw(canvas);
                } else {
                    canvas.translate(scrollX, scrollY);
                    buttonDrawable.draw(canvas);
                    canvas.translate(-scrollX, -scrollY);
                }
            }
        }
    

    这里面有两行代码非常关键
    final int left = isLayoutRtl() ? getWidth() - drawableWidth : 0;
    final int right = isLayoutRtl() ? getWidth() : drawableWidth;
    如果布局是从右往左布局那么勾选框就在右边,布局是从左往右布局那么勾选框就在左边。那么我们就从这里下手修改:

    public class MyCheckBox extends AppCompatCheckBox {
    
        private final Rect rect;
    
        public MyCheckBox(Context context, AttributeSet attrs) {
            super(context, attrs);
            rect = new Rect();
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            Drawable buttonDrawable = CompoundButtonCompat.getButtonDrawable(this);
            if (buttonDrawable != null) {
                final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
                final int drawableHeight = buttonDrawable.getIntrinsicHeight();
                final int drawableWidth = buttonDrawable.getIntrinsicWidth();
    
                final int top;
                switch (verticalGravity) {
                    case Gravity.BOTTOM:
                        top = getHeight() - drawableHeight;
                        break;
                    case Gravity.CENTER_VERTICAL:
                        top = (getHeight() - drawableHeight) / 2;
                        break;
                    default:
                        top = 0;
                }
                final int bottom = top + drawableHeight;
                final int left = getWidth() - drawableWidth;
                final int right = getWidth();
    
                buttonDrawable.setBounds(left, top, right, bottom);
    
                final Drawable background = getBackground();
                if (background != null) {
                    background.setHotspotBounds(left, top, right, bottom);
                }
            }
    
            //简单绘制文字
            TextPaint paint = getPaint();
            paint.setColor(getCurrentTextColor());
            String text = (String) getText();
            paint.getTextBounds(text, 0, text.length(), rect);
            canvas.drawText(text, 0, text.length(), getPaddingLeft(), (getHeight() + rect.height()) / 2, paint);
    
            if (buttonDrawable != null) {
                final int scrollX = getScrollX();
                final int scrollY = getScrollY();
                if (scrollX == 0 && scrollY == 0) {
                    buttonDrawable.draw(canvas);
                } else {
                    canvas.translate(scrollX, scrollY);
                    buttonDrawable.draw(canvas);
                    canvas.translate(-scrollX, -scrollY);
                }
            }
        }
    
    }
    

    写一个类继承AppCompatCheckBox并重写onDraw方法,通过buttonDrawable.setBounds方法将勾选框设置在右边,这样绘制出来的勾选框就在右边,然后绘制需要显示的文字,最后再绘制buttonDrawable就可以了。

    相关文章

      网友评论

        本文标题:勾选框居右显示的AppCompatCheckBox

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