自定义开关按钮

功能描述:

实现一个开关,效果如下:
自定义按钮

功能分析:

  • View的行为 :

    1. click,longClick,
    2. dispatchTouchEvent():touch分发,android希望用来处理是否分发touch事件
    3. onInterceptTouchEvent():touch拦截,android希望处理是否拦截touch事件
      1. 是否拦截孩子touch
    4. onTouchEvent(): touch处理, android希望开发人员封装触摸行为给用户提供交换
    5. setOnTouchListener():
  • View的刷新: invalidate() —> draw() —> onDraw()

  • 回调
    1. setXXXListener设置监听的方法 由提供者创造,用来给 使用者设置监听回调
    2. 提供者 –> onXXXXListener
    3. 提供者 –>调用接口中的方法
    4. 使用者 –>实现接口

代码实现:

  • 布局界面:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.cdw.switchtoggle.MainActivity">

    <com.cdw.switchtoggle.SwitchToggleView
        android:id="@+id/stv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</RelativeLayout>
  • SwitchToggleView.java:
package com.cdw.switchtoggle;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by dongwei on 2016/7/31.
 */
public class SwitchToggleView extends View {
    private Bitmap mSwitchBackground;//背景图片
    private Bitmap mSwitchSlide;//滑块图片

    private final static int STATE_NONE = 0;
    private final static int STATE_DOWN = 1;
    private final static int STATE_MOVE = 2;
    private final static int STATE_UP = 3;

    private boolean isOpened = true;//用来标记滑块是否打开
    private int mState = STATE_NONE;//用来标记状态

    private float mCurrentX;
    private OnSwitchListener mListener;

    private Paint mPaint = new Paint();

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

    public SwitchToggleView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * 设置背景资源
     *
     * @param resId
     */
    public void setSwitchBackground(int resId) {
        mSwitchBackground = BitmapFactory.decodeResource(getResources(), resId);
    }

    public void setSwichSlide(int resId) {
        mSwitchSlide = BitmapFactory.decodeResource(getResources(), resId);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (mSwitchBackground != null) {
            int width = mSwitchBackground.getWidth();
            int height = mSwitchBackground.getHeight();

            setMeasuredDimension(width, height);
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //绘制背景显示
        if (mSwitchBackground != null) {
            int left = 0;
            int top = 0;
            canvas.drawBitmap(mSwitchBackground, left, top, mPaint);
        }

        if (mSwitchSlide == null) {
            return;
        }
        int slideWidth = mSwitchSlide.getWidth();//滑块的宽度
        int switchWidth = mSwitchBackground.getWidth();

        switch (mState) {
            case STATE_DOWN:
            case STATE_MOVE:
                if (!isOpened) {
                    //滑块是关闭的
                    if (mCurrentX < slideWidth / 2f) {
                        //绘制在左侧
                        canvas.drawBitmap(mSwitchSlide, 0, 0, mPaint);
                    } else {
                        float left = mCurrentX - slideWidth / 2f;
                        float maxLeft = switchWidth - slideWidth;
                        if (left > maxLeft) {
                            left = maxLeft;
                        }

                        canvas.drawBitmap(mSwitchSlide, left, 0, mPaint);
                    }
                } else {
                    //滑块是打开的
                    float middle = switchWidth - slideWidth / 2f;
                    if (mCurrentX > middle) {
                        //绘制为打开
                        canvas.drawBitmap(mSwitchSlide, switchWidth - slideWidth, 0, mPaint);
                    } else {
                        float left = mCurrentX - slideWidth / 2f;
                        if (left < 0){
                            left = 0;
                        }
                        canvas.drawBitmap(mSwitchSlide, left, 0, mPaint);
                    }
                }
                break;
            case STATE_UP:
            case STATE_NONE:
                //绘制滑块
                if (!isOpened) {
                    canvas.drawBitmap(mSwitchSlide, 0, 0, mPaint);
                } else {
                    canvas.drawBitmap(mSwitchSlide, switchWidth - slideWidth, 0, mPaint);
                }

                break;
            default:
                break;

        }

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mState = STATE_DOWN;
                mCurrentX = event.getX();

                invalidate();//触发刷新
                break;
            case MotionEvent.ACTION_MOVE:
                mState = STATE_MOVE;
                mCurrentX = event.getX();

                invalidate();//触发刷新
                break;
            case MotionEvent.ACTION_UP:
                mState = STATE_UP;
                invalidate();//触发刷新
                //判断状态改变
                int switchWidth = mSwitchBackground.getWidth();
                mCurrentX = event.getX();
                if (switchWidth / 2f > mCurrentX && isOpened){
                    isOpened = false;
                    if (mListener != null){
                        mListener.onSwitchChange(isOpened);
                    }
                }else if (switchWidth / 2f < mCurrentX && !isOpened){
                    isOpened = true;
                    if (mListener != null){
                        mListener.onSwitchChange(isOpened);
                    }
                }
                break;
            default:
                break;
        }
        //消费touch事件
        return true;
    }

    public void setOnSwitchListener(OnSwitchListener listener){
        this.mListener = listener;
    }

    public interface OnSwitchListener{
        //开关状态改变
        void onSwitchChange(boolean isOpened);
    }
}
  • mainActivity.java
package com.cdw.switchtoggle;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends Activity {

    private SwitchToggleView mView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mView = (SwitchToggleView) findViewById(R.id.stv);

        mView.setSwitchBackground(R.drawable.switch_background);
        mView.setSwichSlide(R.drawable.slide_button_background);

        mView.setOnSwitchListener(new SwitchToggleView.OnSwitchListener() {
            @Override
            public void onSwitchChange(boolean isOpened) {
                Toast.makeText(getApplicationContext(), isOpened ? "打开" : "关闭", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

项目链接https://github.com/ChenDongWei/Android/tree/671a45e83d5884d0ffde92fc3dcb5daf5923b250/switchtoggle

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值