Android自定义Switch开关

在Android4.0中也添加了一个类似的控件:Switch。如下图所示:

其类关系图如下:

这种控件使用起来很简单,但有一定的局限性:
1. 必须在4.0以上的系统中才能使用
2. 原生的UI不太美观
因此,基于上面两点,自定义Switch成为了首选。
SwitchButton.java
package com.jackie.countdowntimer;

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

/**
 * Created by Jackie on 2015/12/15.
 */
public class SwitchButton extends View {
    private Bitmap mSwitchBackgroud, mSlideBackground;

    private int mCurrentX;  //当前X轴偏移量
    private boolean mCurrentState = false;  //当前状态,判断滑块是否滑动成功
    private boolean mIsSliding = false;    //滑块是否正在滑动

    private OnSwitchStateChangeListener mOnSwitchStateChangeListener; //状态改变的回调

    public SwitchButton(Context context, AttributeSet attrs) {
        super(context, attrs);

        initBitmap();
    }

    //初始化开关图片
    private void initBitmap() {
        mSwitchBackgroud = BitmapFactory.decodeResource(getResources(), R.drawable.switch_background);
        mSlideBackground = BitmapFactory.decodeResource(getResources(), R.drawable.slide_button_background);
    }

    //设置当前控件的宽和高
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        // 设置开关的宽和高
        setMeasuredDimension(mSwitchBackgroud.getWidth(), mSwitchBackgroud.getHeight());
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //绘制背景
        canvas.drawBitmap(mSwitchBackgroud, 0, 0, null);

        if (mIsSliding) {  //正在滑动中
            int left = mCurrentX - mSlideBackground.getWidth();
            if (left < 0) {  //超过左边界
                left = 0;
            } else if (left > mSwitchBackgroud.getWidth() - mSlideBackground.getWidth()) { //超出右边界
                left = mSwitchBackgroud.getWidth() - mSlideBackground.getWidth();
            }

            canvas.drawBitmap(mSlideBackground, left, 0, null);
        } else {
            if (mCurrentState) {
                //绘制开关开的状态
                int left = mSwitchBackgroud.getWidth() - mSlideBackground.getWidth();
                canvas.drawBitmap(mSlideBackground, left, 0, null);
            } else {
                //绘制开关关的状态
                canvas.drawBitmap(mSlideBackground, 0, 0, null);
            }
        }

        super.onDraw(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mCurrentX = (int) event.getX();
                mIsSliding = true;
                break;
            case MotionEvent.ACTION_MOVE:
                mCurrentX = (int) event.getX();
                break;
            case MotionEvent.ACTION_UP:
                mCurrentX = (int) event.getX();
                mIsSliding = false;

                int center = mSwitchBackgroud.getWidth() / 2;
                boolean state = mCurrentX > center;   //滑块滑动的距离超过背景的一半,表示滑动成功,状态需要改变

                if (mCurrentState != state && mOnSwitchStateChangeListener != null) {  //两个状态不一样,表示滑动已经滑动成功,状态改变
                    mOnSwitchStateChangeListener.onSwitchStateChange(state);
                }

                mCurrentState = state;
                break;
        }

        invalidate();
        return true;
    }

    /**
     * 设置开关的状态
     * @param state
     */
    public void setSwitchState(boolean state) {
        mCurrentState = state;
    }

    public void setOnSwitchStateChangeListener(OnSwitchStateChangeListener onSwitchStateChangeListener) {
        this.mOnSwitchStateChangeListener = onSwitchStateChangeListener;
    }
}

OnSwitchStateChangeListener.java

package com.jackie.countdowntimer;

/**
 * Created by Jackie on 2015/12/15.
 */
public interface OnSwitchStateChangeListener {
    /**
     * 当开关状态改变时回调此方法
     * @param state 开关当前的状态
     */
    void onSwitchStateChange(boolean state);
}
在xml中作如下定义:
<com.jackie.countdowntimer.SwitchButton
        android:id="@+id/switcher"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/verify_code"
        />
使用方法:
        mSwitchButton = (SwitchButton) findViewById(R.id.switcher);
        mSwitchButton.setSwitchState(true);
        mSwitchButton.setOnSwitchStateChangeListener(new OnSwitchStateChangeListener() {
            @Override
            public void onSwitchStateChange(boolean state) {
                if (state) {
                    Toast.makeText(MainActivity.this, "开关打开了", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(MainActivity.this, "开关关闭了", Toast.LENGTH_SHORT).show();
                }
            }
        });
最后附上所用的资源图片:
   
效果图如下:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android自定义Switch控件可以通过自定义drawable来实现。以下是一个简单的例子: 1. 创建一个drawable资源文件,例如 switch_bg.xml,用于定义Switch的背景样式: ```xml <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_checked="true" android:drawable="@drawable/switch_on_bg" /> <item android:state_checked="false" android:drawable="@drawable/switch_off_bg" /> </selector> ``` 2. 创建两个drawable资源文件,例如 switch_on_bg.xml 和 switch_off_bg.xml,分别用于定义Switch开和关状态下的样式。 switch_on_bg.xml: ```xml <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#00FF00" /> <corners android:radius="20dp" /> </shape> ``` switch_off_bg.xml: ```xml <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#FF0000" /> <corners android:radius="20dp" /> </shape> ``` 3. 在布局文件中使用自定义Switch控件: ```xml <Switch android:id="@+id/customSwitch" android:layout_width="wrap_content" android:layout_height="wrap_content" android:thumb="@drawable/custom_switch_thumb" android:track="@drawable/switch_bg" /> ``` 其中,android:thumb属性定义了Switch的拇指(即开关按钮)的样式。我们可以创建一个自定义drawable来实现: ```xml <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="#FFFFFF" /> <size android:width="20dp" android:height="20dp" /> </shape> ``` 这样就完成了自定义Switch控件的样式。当Switch状态改变时,背景样式也会随之改变。你可以根据自己的需求来修改样式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值