当前位置: 首页 > 编程笔记 >

Android自定义控件仿iOS滑块SwitchButton

时衡虑
2023-03-14
本文向大家介绍Android自定义控件仿iOS滑块SwitchButton,包括了Android自定义控件仿iOS滑块SwitchButton的使用技巧和注意事项,需要的朋友参考一下

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


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 本文向大家介绍Android仿IOS自定义AlertDialog提示框,包括了Android仿IOS自定义AlertDialog提示框的使用技巧和注意事项,需要的朋友参考一下 本文介绍的仿IOS对话框的实现,先来看一下效果图 具体代码如下: 布局文件view_alertdialog.xml alertdialog_left_selector.xml alertdialog_right_select

  • 我想自定义滑块显示的数据。例如,与其显示一个数字,不如说是“前缀”数字“后缀”,而且这个值应该始终可见。 在类VSlider我找到了方法。我怀疑这是配置滑块显示的值的地方。我尝试用相同的包结构在我自己的项目中复制这个类,我还重新编译了小部件集,但是视图中没有显示这些更改。我刚开始为Vaadin创建客户端代码,所以可能有一些我不理解的地方。 问题: 你对我如何实现我的目标有什么建议吗? 您知道为什么

  • 本文向大家介绍Android自定义view仿IOS开关效果,包括了Android自定义view仿IOS开关效果的使用技巧和注意事项,需要的朋友参考一下 本文主要讲解如何在 Android 下实现高仿 iOS 的开关按钮,并非是在 Android 自带的 ToggleButton 上修改,而是使用 API 提供的 onDraw、onMeasure、Canvas 方法,纯手工绘制。基本原理就是在 Ca

  • Tabris.js控件由JavaScript API和原生平台的实现组成。本文档介绍Android平台上的自定义控件的原生实现。 为了实现自定义控件你需要本地构建。 在Cordova基础上构建 为了创建Tabris.js自定义控件,我们使用Cordova的构建系统。因此,我们创建一个与Tabris.js特定的API相关联的Cordova插件。Tabris.js自定义控件不需要接触任何Cordova

  • 本文向大家介绍Android自定义星星可滑动评分控件,包括了Android自定义星星可滑动评分控件的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Android自定义星星可滑动评分控件的具体方法,供大家参考,具体内容如下 此控件通过线性布局结合ImageView来实现。 具有展示分数,滑动评分功能,可设置0-10分,自行设置星星图片,是否可点击与滑动,星星间距。 效果如下: 需准备好

  • 本文向大家介绍Android自定义控件之自定义组合控件(三),包括了Android自定义控件之自定义组合控件(三)的使用技巧和注意事项,需要的朋友参考一下 前言: 前两篇介绍了自定义控件的基础原理Android自定义控件基本原理详解(一)、Android自定义控件之自定义属性(二)。今天重点介绍一下如何通过自定义组合控件来提高布局的复用,降低开发成本,以及维护成本。 使用自定义组合控件的好处? 我