Android:自定义ToggleButton

先看效果:

ToggleButton

实现思路 :

仿照系统自带的ToggleButton控件,继承系统CompoundButton类,然后重写onDraw方法

代码如下:

public class ToggleButton extends CompoundButton {
    private static final String TAG = "ToggleButton";
    //背景画笔(画下面的背景)
    private Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    //开关画笔(画上面的小圆)
    private Paint togglePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    //背景路径
    private Path backgroundPath = new Path();
    //打开时上面圆的路径
    private Path togglePath_on = new Path();
    //关闭时上面圆的路径
    private Path togglePath_off = new Path();
    //上面圆和底部背景之间的间距
    private float padding =1;
    //onDraw时的路径
    private Path toggleDrawPath = new Path();
    //打开的颜色
    private int onColor;
    //关闭的颜色
    private int offColor;

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

    public ToggleButton(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public void setOffColor(int offColor) {
        this.offColor = offColor;
    }

    public void setOnColor(int onColor) {
        this.onColor = onColor;
    }

    public void setPadding(int padding) {
        this.padding = padding;
    }

    public ToggleButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //设置可点击
        this.setClickable(true);
        initAttrs(attrs);
        initPaints();
    }

    /**
     * 初始化画笔
     */
    private void initPaints() {
        togglePaint.setColor(Color.WHITE);
    }

    /**
     * 初始化attrs
     * @param attrs
     */
    private void initAttrs(AttributeSet attrs){
        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ToggleButton);
        onColor = a.getColor(R.styleable.ToggleButton_onColor,Color.GREEN);
        offColor = a.getColor(R.styleable.ToggleButton_offColor, Color.LTGRAY);
        a.recycle();
    }


    /**
     * 初始化Paths
     */
    private void initPath() {
        int height = getHeight();
        int width = getWidth();
        if (height > 0 && width > 0) {
            int radius = Math.min(width, height) / 2;
            backgroundPath.reset();
            togglePath_on.reset();
            togglePath_off.reset();
            RectF left = new RectF(0, 0, 2 * radius, 2 * radius);
            RectF right = new RectF(width - 2 * radius, 0, width, height);
            backgroundPath.addArc(left, 90, 180);
            backgroundPath.addRect(radius, 0, width - radius, height, Path.Direction.CCW);
            backgroundPath.addArc(right, 270, 180);

            RectF on = new RectF(width - 2 * radius - padding, padding, width - padding, height - padding);
            RectF off = new RectF(padding, padding, 2 * radius - padding, 2 * radius - padding);
            togglePath_on.addArc(on, 90, 360);
            togglePath_off.addArc(off, 90, 360);
            toggleDrawPath.set(isChecked()?togglePath_on : togglePath_off);
        }

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        backgroundPaint.setColor(isChecked() ? onColor : offColor);
        canvas.drawPath(backgroundPath, backgroundPaint);
        canvas.drawPath(toggleDrawPath, togglePaint);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        if(widthMode != MeasureSpec.EXACTLY){
            widthSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, displayMetrics);
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
        }

        if(heightMode != MeasureSpec.EXACTLY){
            heightSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, displayMetrics);
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        initPath();
    }

    @Override
    public void setChecked(boolean checked) {
        super.setChecked(checked);
        boolean isChecked = isChecked();
        if (toggleDrawPath != null) {
            toggleDrawPath.reset();
            toggleDrawPath.set(isChecked?togglePath_on : togglePath_off);
        }
        invalidate();
    }
}

添加监听 :

ToggleButton toggleButton = (ToggleButton) findViewById(R.id.toggleButton);
toggleButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
               // do something
        });

自定义属性 :

<declare-styleable name="ToggleButton">
        <attr name="onColor" format="color|reference"/>
        <attr name="offColor" format="color|reference"/>
</declare-styleable>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值