大家好,今天给大家分享的是自定义控件开关,这在自定义控件中是个非常重要的知识点,所以我把它作为例子给大家讲解,加深对自定义控件的认识,在开发中,很常涉及到要自己自定义控件,这必然要引起大家极其的关注。
创建MySwitch继承View,实现自定义
public class MySwitch extends View {
private Bitmap mBitmapBg;//图片背景
private Bitmap mBitmap;//移动图片
private int max_left;//最大边距
private int mSigleBitmap;//滑动的变量
private boolean isOpean;//判断是打开还是关闭状态
private onCheckChangeListenter mListener;//回调监听
private int startX;
private int endX;
boolean isClick;//判断是点击还是触摸
int moveX;.//移动的总距离,根据移动的距离,判断是点击事件还是触摸事件
//构造方法
public MySwitch(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView();// 初始化组件
}
public MySwitch(Context context, AttributeSet attrs) {
super(context, attrs);
initView();// 初始化组件
}
public MySwitch(Context context) {
super(context);
initView();// 初始化组件
}
// 初始化组件
private void initView() {
//获取图片,使用BitmapFactory.decodeResource获取
mBitmapBg = BitmapFactory.decodeResource(getResources(),
R.drawable.switch_background);
mBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.slide_button);
//得到最大边距
max_left = mBitmapBg.getWidth() - mBitmap.getWidth();
//控件的点击事件,点击的是滑块
setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//当是点击事件执行这方法
if (isClick) {
//如果是打开状态
if (isOpean) {
//滑动变量为0,状态改变
mSigleBitmap = 0;
isOpean = false;
//如果是关闭状态
} else {
//滑动变量为最大左边距,状态改变
mSigleBitmap = max_left;
isOpean = true;
}
//刷新数据
invalidate();
//3.点击开始回调,回调相关数据
if (mListener != null) {
mListener.onCheckChange(MySwitch.this, isOpean);
}
}
}
});
}
//测量,设置控件的大小
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//设置是以背景的长宽作为控件的大小
setMeasuredDimension(mBitmapBg.getWidth(), mBitmapBg.getHeight());
}
/**
* 1.定义回调函数接口
*/
public interface onCheckChangeListenter {
public void onCheckChange(View view, boolean isCheck);
}
/**
* 2.暴露方法,回调监听,构造方法
*
*/
public void setOnCheckChangeListenter(onCheckChangeListenter listenter) {
this.mListener = listenter;
}
//触摸事件
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//刚开始按下的坐标x
startX = (int) event.getX();
break;
case MotionEvent.ACTION_MOVE:
//移动时坐标x,也就是最后点击的坐标x
endX = (int) event.getX();
//计算滑动的偏移量
int dx = endX - startX;
//根据偏移量更新划片的位置
mSigleBitmap = mSigleBitmap + dx;
//移动的总距离,绝对值,可能有负数
moveX = Math.abs(moveX + dx);
//判断不能越界
if (mSigleBitmap < 0) {
mSigleBitmap = 0;
}
if (mSigleBitmap > max_left) {
mSigleBitmap = max_left;
}
// 刷新页面
invalidate();
//重新获取起始点
startX = (int) event.getX();
break;
case MotionEvent.ACTION_UP:
//移动总距离大于5,则是触摸事件
if (moveX > 5) {
isClick = false;
//反之,则是点击事件
} else {
isClick = true;
}
//清除总移动值
moveX = 0;
//当是触摸事件时,
if (!isClick) {
//判断滑动的变量与最大左边距对比,
if (mSigleBitmap < max_left / 2) {
mSigleBitmap = 0;
isOpean = false;
} else {
mSigleBitmap = max_left;
isOpean = true;
}
// 刷新页面
invalidate();
//触摸事件的回调方法,回调相关的数据
if (mListener != null) {
mListener.onCheckChange(MySwitch.this, isOpean);
}
}
break;
default:
break;
}
return super.onTouchEvent(event);
}
//在自定义控件执行的方法:onMeasure-->onLayout--->onDraw
protected void onDraw(Canvas canvas) {
//绘制图片
canvas.drawBitmap(mBitmapBg, 0, 0, null);
//绘制滑块图片,参数二:变量
canvas.drawBitmap(mBitmap, mSigleBitmap, 0, null);
}
}
MainActivity.java实现监听事件
public class MainActivity extends Activity {
private MySwitch mMySwitch;//自定义控件
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMySwitch=(MySwitch) findViewById(R.id.div_myswitch);
//调用回调函数,因为是自定义控件本身是没有属性方法的,需要创建,然后回调,不像,本身自带的控件有属于自己的方法
mMySwitch.setOnCheckChangeListenter(new onCheckChangeListenter() {
@Override
public void onCheckChange(View view, boolean isCheck) {
Toast.makeText(MainActivity.this, "开关状态::"+isCheck, 2000).show();
}
});
今晚的自定义开关控件就到这里,相信大家看完之后能有所收获。晚安