自定义控件之仿IOS的ToggleButton

本文介绍了一个自定义的开关按钮组件MyToggleButton的实现方法。该组件可在Android应用中使用,通过滑动来改变开关状态,并提供了回调接口以通知状态变化。

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

1、MyToggleButton.java

package com.cbitcn.togglebuttondemo;

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;

public class MyToggleButton extends View {
	private Bitmap backgroundBmp; // 背景图片
	private Bitmap slideButtonBmp; // 滑动按钮
	private boolean open; // 是否打开
	private int pressX; // 按下的X坐标
	private boolean isSlide = false; //判断当前是否处于滑动状态
	private ToggleButtonCheckListener toggleButtonCheckListener;

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

	public void setToggleButtonBackGround(int background, int slideButton) {
		backgroundBmp = BitmapFactory
				.decodeResource(getResources(), background);
		slideButtonBmp = BitmapFactory.decodeResource(getResources(),
				slideButton);
	}

	/**
	 * 初始化当前ToggleButton的状态
	 * @param open
	 */
	public void initStatus(boolean open) {
		this.open = open;
	}
	
	/**
	 * 设置监听器
	 * @param toggleButtonCheckListener
	 */
	public void setListener(ToggleButtonCheckListener toggleButtonCheckListener){
		this.toggleButtonCheckListener = toggleButtonCheckListener;
	}

	/**
	 * 该方法是其父控件用来测量当前控件的大小,父控件调用时传入的两个参数是宽度和高度的规格
	 * 一共有三种模式,
	 * UNSPECIFIED
	 * EXACTLY,match_parent和具体数值的大小对应这种模式
	 * AT_MOST,wrap_content对应这种模式
	 */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		// 设置该控制MyToggleButton的大小
		setMeasuredDimension(backgroundBmp.getWidth(),
				backgroundBmp.getHeight());
	}

	/**
	 * 控件的显示就是调用该方法绘制出来的
	 */
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		// 绘制背景,第二和第三个参数,绘制的背景相对于该控件的顶部和左边的距离
		canvas.drawBitmap(backgroundBmp, 0, 0, null);
		// 绘制滑动按钮
		if (isSlide) {
			int left = pressX - slideButtonBmp.getWidth() / 2;
			if (left < 0) {
				left = 0;
			} else if (left > backgroundBmp.getWidth()
					- slideButtonBmp.getWidth()) {
				left = backgroundBmp.getWidth() - slideButtonBmp.getWidth();
			}
			canvas.drawBitmap(slideButtonBmp, left, 0, null);
		} else {
			if (open) {
				canvas.drawBitmap(slideButtonBmp, backgroundBmp.getWidth()
						- slideButtonBmp.getWidth(), 0, null);
			} else {
				canvas.drawBitmap(slideButtonBmp, 0, 0, null);
			}
			//回调
			toggleButtonCheckListener.check(open);
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		pressX = (int) event.getX();

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

			break;
		case MotionEvent.ACTION_UP:
			isSlide = false;
			int middle = backgroundBmp.getWidth() / 2;
			if (pressX < middle) {
				open = false;
			} else {
				open = true;
			}
			break;

		default:
			break;
		}
		// 手动执行onDraw方法
		invalidate();
		return true;
	}
	
	/**
	 * 回调接口
	 * @author Administrator
	 *
	 */
	public interface ToggleButtonCheckListener {
		public void check(boolean status);
	}

}

2、MainActivity.java

public class MainActivity extends Activity {
	private MyToggleButton toggleButton;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		toggleButton = (MyToggleButton) findViewById(R.id.toggle_button);
		toggleButton.setToggleButtonBackGround(R.drawable.switch_background,
				R.drawable.slide_button_background);
		toggleButton.initStatus(false);

		toggleButton.setListener(new ToggleButtonCheckListener() {
			@Override
			public void check(boolean status) {
				if (status) {
					Toast.makeText(MainActivity.this, "打开", Toast.LENGTH_SHORT)
							.show();
				} else {
					Toast.makeText(MainActivity.this, "关闭", Toast.LENGTH_SHORT)
							.show();
				}
			}
		});
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值