首页 > 系统 > Android > 正文

Android自定义控件仿iOS滑块SwitchButton

2019-10-21 21:31:39
字体:
来源:转载
供稿:网友

SwitchButton可以点击的时候切换状态,类似CheckBox

在拖动的时候,也可以根据拖动的距离判断是否切换状态,类似ToggleButton

因此要区别出单击事件和拖动事件

实现效果如图所示:

Android,iOS,滑块,SwitchButton

自定义的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个资源图片:

Android,iOS,滑块,SwitchButtonAndroid,iOS,滑块,SwitchButtonAndroid,iOS,滑块,SwitchButton

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


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表