Android 滑动开关按钮

本文介绍了一种自定义的Android滑动开关控件实现方法。该控件可根据用户手势在开启与关闭两种状态间切换,并通过监听接口反馈状态改变。文章提供了完整的代码示例及如何使用自定义属性来配置不同状态下的背景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

刚看了一篇博客地址:http://blog.youkuaiyun.com/xiaanming/article/details/8842453

个人技术水平有限,在原基础上整理出自定义控件代码如下:

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.example.swipercheck.R;

@SuppressLint({ "ClickableViewAccessibility", "DrawAllocation" })
public class SwipperView extends View {

	/** 关闭的图片资源 */
	private Drawable mBitmapOpenDrawable;
	/** 打开的图片资源 */
	private Drawable mBitmapCloseDrawable;
	/** 拖拽的图片资源 */
	private Drawable mBitmapSlipDrawable;
	/** 是否在滑动 */
	private boolean isScroll;
	/** 关闭的图片 */
	private Bitmap mBitmapClose;
	/** 打开的图片 */
	private Bitmap mBitmapOpen;
	/** 拖拽的图片 */
	private Bitmap mBitmapSlip;
	/** 自定义属性文件 */
	private int[] mDefStyleAttr=R.styleable.Swipper;
	private float mCurrX;
	private boolean mCurrStatus;

	
	public SwipperView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		// TODO Auto-generated constructor stub
		TypedArray mTypeArray = context.obtainStyledAttributes(attrs,
				mDefStyleAttr);
		// 获取自定义属性值
		mBitmapCloseDrawable= mTypeArray.getDrawable(
				R.styleable.Swipper_backgroundClose);
		mBitmapOpenDrawable= mTypeArray.getDrawable(
				R.styleable.Swipper_backgroundOpen);
		mBitmapSlipDrawable= mTypeArray.getDrawable(
				R.styleable.Swipper_backgroundSwipper);

		// 获取图片资源
		mBitmapClose = drawableToBitamp(mBitmapCloseDrawable);
		mBitmapOpen= drawableToBitamp(mBitmapOpenDrawable);
		mBitmapSlip= drawableToBitamp(mBitmapSlipDrawable);

		mTypeArray.recycle();
	}

	public SwipperView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
		// TODO Auto-generated constructor stub
	}

	public SwipperView(Context context) {
		this(context, null);
		// TODO Auto-generated constructor stub
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub

		mCurrX = event.getX();

		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			isScroll = true;
			break;
		case MotionEvent.ACTION_MOVE:
			break;

		case MotionEvent.ACTION_UP:
			isScroll = false;
			if (mCurrX>= mBitmapClose.getWidth() / 2) {
				// 滑动距离可以滑动过去,当前状态打开
				mCurrX = mBitmapClose.getWidth() - mBitmapSlip.getWidth();
				mCurrStatus = true;
			} else {
				// 滑动距离不够,当前状态关闭
				mCurrX = 0;
				mCurrStatus = false;
			}
			if(mListener != null){
				mListener.onSwipperChange(mCurrStatus);
			}
			break;
		default:
			break;
		}
		invalidate();
		return true;
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		Matrix matrix = new Matrix();
		Paint mPaint = new Paint();
		
		float x = 0;
		if (mCurrX < (mBitmapClose.getWidth() / 2)) {
			canvas.drawBitmap(mBitmapClose, matrix, mPaint);
		} else {
			canvas.drawBitmap(mBitmapOpen, matrix, mPaint);
		}

		if (isScroll) {// 是否是在滑动状态,
			if (mCurrX >= mBitmapClose.getWidth())// 是否划出指定范围,不能让滑块跑到外头,必须做这个判断
				x = mBitmapClose.getWidth() - mBitmapSlip.getWidth() / 2;// 减去滑块1/2的长度
			else
				x = mCurrX - mBitmapSlip.getWidth() / 2;
		} else {
			if (mCurrStatus) {// 根据当前的状态设置滑块的x值
				x = mBitmapClose.getWidth() - mBitmapSlip.getWidth();
			} else {
				x = 0;
			}
		}

		// 对滑块滑动进行异常处理,不能让滑块出界
		if (x < 0) {
			x = 0;
		} else if (x > mBitmapClose.getWidth() - mBitmapSlip.getWidth()) {
			x = mBitmapClose.getWidth() - mBitmapSlip.getWidth();
		}

		// 画出滑块
		canvas.drawBitmap(mBitmapSlip, x, 0, mPaint);

	}

	/**
	 * 监听开关变化接口
	 * 
	 * @author Administrator
	 * 
	 */
	public interface OnSwipperListener {
		void onSwipperChange(boolean isOpen);
	}

	private OnSwipperListener mListener;

	public OnSwipperListener getmListener() {
		return mListener;
	}

	public void setmListener(OnSwipperListener mListener) {
		this.mListener = mListener;
	}

	/**
	 * 设置滑动开关的初始状态,供外部调用
	 * @param checked
	 */
	public void setChecked(boolean checked){
		if(checked){
			mCurrX = mBitmapClose.getWidth();
		}else{
			mCurrX = 0;
		}
		mCurrStatus = checked;
	}


	/***
	 * Bitmap Drawable 转换
	 * @param drawable
	 * @return
	 */
	private Bitmap drawableToBitamp(Drawable drawable)
	{
		 Bitmap mBitmap=null;
		 BitmapDrawable bd = (BitmapDrawable) drawable;
		 mBitmap= bd.getBitmap();
		return mBitmap;
	}

}
attr.xml

<resources>

    <declare-styleable name="Swipper">
        <attr name="backgroundClose" format="color|reference" />
        <attr name="backgroundOpen" format="color|reference" />
        <attr name="backgroundSwipper" format="color|reference" />
    </declare-styleable>

</resources>


备注说明:.9.png图片获取成Drawable不能bitmapDrawable,否则会报错

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值