Android开发Android开发经验谈Android技术知识

勾选框居右显示的AppCompatCheckBox

2019-12-16  本文已影响0人  blingbling_5a3f

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就可以了。

上一篇下一篇

猜你喜欢

热点阅读