Android自定义控件仿iOS滑块SwitchButton
程序员文章站
2022-04-12 11:32:22
switchbutton可以点击的时候切换状态,类似checkbox
在拖动的时候,也可以根据拖动的距离判断是否切换状态,类似togglebutton
因此要区别出单击...
switchbutton可以点击的时候切换状态,类似checkbox
在拖动的时候,也可以根据拖动的距离判断是否切换状态,类似togglebutton
因此要区别出单击事件和拖动事件
实现效果如图所示:
自定义的switchbutton如下:
public class switchbutton extends view implements view.ontouchlistener { private bitmap bg_on, bg_off, slipper_btn; /** * 按下时的x和当前的x */ private float downx, nowx; /** * 记录用户是否在滑动 */ private boolean onslip = false; /** * 当前的状态 */ private boolean nowstatus = false; /** * 监听接口 */ private onchangedlistener listener; /** * 一个滑动的距离临界值,判断是滑动还是点击 * getscaledtouchslop(): * distance in pixels a touch can wander before we think the user is scrolling * */ private int mtouchslop=new viewconfiguration().getscaledtouchslop(); public switchbutton(context context) { super(context); init(); } public switchbutton(context context, attributeset attrs) { super(context, attrs); init(); } public void init(){ //载入图片资源 bg_on = bitmapfactory.decoderesource(getresources(), r.mipmap.switch_on_on); bg_off = bitmapfactory.decoderesource(getresources(), r.mipmap.switch_off_off); slipper_btn = bitmapfactory.decoderesource(getresources(), r.mipmap.switch_ball_ball); setontouchlistener(this); } protected void ondraw(canvas canvas) { super.ondraw(canvas); matrix matrix = new matrix(); paint paint = new paint(); float x = 0; //根据nowx设置背景,开或者关状态 if (nowx < (bg_on.getwidth()/2)){ canvas.drawbitmap(bg_off, matrix, paint);//画出关闭时的背景 }else{ canvas.drawbitmap(bg_on, matrix, paint);//画出打开时的背景 } if (onslip) {//是否是在滑动状态, if(nowx >= bg_on.getwidth())//是否划出指定范围,不能让滑块跑到外头,必须做这个判断 x = bg_on.getwidth() - slipper_btn.getwidth()/2;//减去滑块1/2的长度 else x = nowx - slipper_btn.getwidth()/2; }else { if(nowstatus){//根据当前的状态设置滑块的x值 x = bg_on.getwidth() - slipper_btn.getwidth(); }else{ x = 0; } } //对滑块滑动进行异常处理,不能让滑块出界 if (x < 0 ){ x = 0; } else if(x > bg_on.getwidth() - slipper_btn.getwidth()){ x = bg_on.getwidth() - slipper_btn.getwidth(); } //画出滑块 canvas.drawbitmap(slipper_btn, x, 0, paint); } @override public boolean ontouch(view v, motionevent event) { switch(event.getaction()){ case motionevent.action_down:{ if (event.getx() > bg_off.getwidth() || event.gety() > bg_off.getheight()){ return false; }else{ onslip = true; downx = event.getx(); nowx = downx; } break; } case motionevent.action_move:{ nowx = event.getx(); break; } case motionevent.action_up:{ debuglog.e("mtouchslop:"+mtouchslop); onslip = false; nowx = event.getx(); float float_distance=nowx - downx; int int_disatnce=(int)float_distance; debuglog.e("int_disatnce:"+int_disatnce); /** * 滑动距离太短,认定是点击事件 */ if(math.abs(int_disatnce)<mtouchslop){ if(this.ischecked()){ this.setchecked(false); nowx = 0; }else{ this.setchecked(true); nowx = bg_on.getwidth() - slipper_btn.getwidth(); } }else{ /** * 滑动距离足够,认为是滑动事件 */ if(event.getx() >= (bg_on.getwidth()/2)){ nowstatus = true; nowx = bg_on.getwidth() - slipper_btn.getwidth(); }else{ nowstatus = false; nowx = 0; } } if(listener != null){ listener.onchanged(switchbutton.this, nowstatus); } break; } } //刷新界面 invalidate(); return true; } /** * 为wiperswitch设置一个监听,供外部调用的方法 * @param listener */ public void setonchangedlistener(onchangedlistener listener){ this.listener = listener; } /** * 设置滑动开关的初始状态,供外部调用 * @param checked */ public void setchecked(boolean checked){ if(checked){ nowx = bg_off.getwidth(); }else{ nowx = 0; } nowstatus = checked; } public boolean ischecked() { return nowstatus; } /** * 回调接口 * */ public interface onchangedlistener { public void onchanged(switchbutton wiperswitch, boolean checkstate); } }
布局文件中使用:
<com.uestcneon.chuji.changjianglife.share.switchbutton android:id="@+id/user_privacy_state" android:layout_width="wrap_content" android:layout_height="20dp" android:layout_marginleft="30dp" />
控件用到的3个资源图片:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。