当前位置: 移动技术网 > 移动技术>移动开发>Android > Android自定义控件仿iOS滑块SwitchButton

Android自定义控件仿iOS滑块SwitchButton

2019年07月30日  | 移动技术网移动技术  | 我要评论

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个资源图片:


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网