Android-自定义滑动按钮
来源:互联网 发布:淘宝圈椅三件套 编辑:程序博客网 时间:2024/06/06 02:22
效果图:
layout布局:
<com.doudoubird.droidzou.newflashlightrevision.widget.SwitchVerticalSlide android:id="@+id/control" android:layout_centerHorizontal="true" android:layout_marginTop="40dp" android:layout_below="@id/background_four" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:src="@mipmap/track_off" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ImageView android:src="@mipmap/track_button_close" android:layout_gravity="bottom" android:layout_width="wrap_content" android:layout_height="wrap_content" /></com.doudoubird.droidzou.newflashlightrevision.widget.SwitchVerticalSlide>
自定义SwitchVerticalSlide:
public class SwitchVerticalSlide extends FrameLayout { private SwitchSlideListener slideListener; private Context mContext; public SwitchVerticalSlide(Context context) { this(context,null); } public SwitchVerticalSlide(Context context, @Nullable AttributeSet attrs) { this(context, attrs,0); } public SwitchVerticalSlide(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext=context; } public void addSlideListener(SwitchSlideListener slideListener){ this.slideListener=slideListener; } private static final int maxSlideInterval=15;//点击时在垂直方向可抖动的误差 private float downP; private float trackHeight; private float trackButtonWidth; private float trackButtonHeight; private float downX; private float downY; private boolean trackLocation=true; private boolean antiShakeFlag;//抗抖动,用于处理点击事件 private boolean isFirstDownLoad; private View child0; private View child1; private float orbitalTransferLength;//滑动时改变按钮状态的滑动距离 private boolean onFinishInflateFlag; private int onFinishInflateState;//1:打开状态,2:关闭状态 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (!isFirstDownLoad){ trackHeight=getChildAt(0).getMeasuredHeight(); trackButtonWidth=getChildAt(1).getMeasuredWidth(); trackButtonHeight=getChildAt(1).getMeasuredHeight(); child0=getChildAt(0); child1=getChildAt(1); isFirstDownLoad=true; orbitalTransferLength=trackHeight/5.0f; } } public void onResumeFinishInflate() { if (onFinishInflateFlag){ switch (onFinishInflateState) { case 1: openSwitch(); onFinishInflateState=0; break; case 2: closeSwitch(); onFinishInflateState=0; break; } onFinishInflateFlag=false; } } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: antiShakeFlag=false; downP=event.getRawY(); downX=event.getX(); downY=event.getY(); break; case MotionEvent.ACTION_MOVE: if (trackLocation){ float dValue = event.getRawY() - downP; if(isInTrackButton(downX,downY, true)){ if (dValue<0){ if(-dValue>orbitalTransferLength){ ((ImageView) child1).setImageResource(R.mipmap.track_button_open); ((ImageView) child0).setImageResource(R.mipmap.track_on); }else { ((ImageView) child1).setImageResource(R.mipmap.track_button_close); ((ImageView) child0).setImageResource(R.mipmap.track_off); } //抗抖动 if (antiShakeFlag|dValue<-maxSlideInterval){ //在按下点之向上滑动 antiShakeFlag=true; float maxValue = trackButtonHeight - trackHeight; if (dValue> maxValue){ child1.setTranslationY(dValue); }else { child1.setTranslationY(maxValue); } } }else { if (dValue>maxSlideInterval){ antiShakeFlag=true; } child1.setTranslationY(0); } }else{ //如果在这个区域内,垂直方向超过了10,则需要改变 antiShakeFlag 取消点击 if (Math.abs(dValue)>maxSlideInterval){ antiShakeFlag=true; } } }else { float dValue = event.getRawY() - downP; if (isInTrackButton(downX,downY,false)){ if (dValue>0){ if(dValue>orbitalTransferLength){ ((ImageView) child1).setImageResource(R.mipmap.track_button_close); ((ImageView) child0).setImageResource(R.mipmap.track_off); }else { ((ImageView) child1).setImageResource(R.mipmap.track_button_open); ((ImageView) child0).setImageResource(R.mipmap.track_on); } if (antiShakeFlag|dValue>maxSlideInterval){ //在按下点之下滑动 antiShakeFlag=true; float maxValue = trackButtonHeight - trackHeight + dValue; if (maxValue<0){ child1.setTranslationY(maxValue); }else { child1.setTranslationY(0); } } }else { if (dValue<-maxSlideInterval){ antiShakeFlag=true; } child1.setTranslationY(trackButtonHeight-trackHeight); } }else { if (Math.abs(dValue)>maxSlideInterval){ antiShakeFlag=true; } } } break; case MotionEvent.ACTION_UP: if (!antiShakeFlag){ //第一次按下滑动距离不超过20,视为点击 if (trackLocation){ ((ImageView) child1).setImageResource(R.mipmap.track_button_open); ((ImageView) child0).setImageResource(R.mipmap.track_on); getChildAt(1).setTranslationY(trackButtonHeight-trackHeight); trackLocation=false; slideListener.onSwitchSlide(true); }else { ((ImageView) child1).setImageResource(R.mipmap.track_button_close); ((ImageView) child0).setImageResource(R.mipmap.track_off); child1.setTranslationY(0); trackLocation=true; slideListener.onSwitchSlide(false); } }else { if (trackLocation){ if(isInTrackButton(downX,downY, true)){ if((downP-event.getRawY())>orbitalTransferLength){ //打开开关 trackLocation=false; child1.setTranslationY(trackButtonHeight-trackHeight); slideListener.onSwitchSlide(true); }else { child1.setTranslationY(0); } } }else{ if(isInTrackButton(downX,downY, false)){ if((event.getRawY()-downP)>orbitalTransferLength){ //关闭开关 trackLocation=true; child1.setTranslationY(0); slideListener.onSwitchSlide(false); }else { child1.setTranslationY(trackButtonHeight-trackHeight); } } } } break; } return true; } public void openSwitch(){ if (child0!=null&&child1!=null) { ((ImageView) child1).setImageResource(R.mipmap.track_button_open); ((ImageView) child0).setImageResource(R.mipmap.track_on); child1.setTranslationY(trackButtonHeight-trackHeight); trackLocation=false; }else { onFinishInflateFlag=true;//完成加载后改变状态 onFinishInflateState=1; } } public void closeSwitch(){ if (child0!=null&&child1!=null) { ((ImageView) child1).setImageResource(R.mipmap.track_button_close); ((ImageView) child0).setImageResource(R.mipmap.track_off); child1.setTranslationY(0); trackLocation=true; }else { onFinishInflateFlag=true;//完成加载后改变状态 onFinishInflateState=2; } } /** * * @param downX * @param downY * @param down true表示按钮在下面,false表示按钮在上面 * @return true 在矩形内,false 不在矩形内 */ private boolean isInTrackButton(float downX,float downY,boolean down){ float leftUpX=0.0f; float rightDownX=trackButtonWidth; float leftUpY; float rightDownY; if (down){ leftUpY=trackHeight-trackButtonHeight; rightDownY=trackHeight; }else { leftUpY=0; rightDownY=trackButtonHeight; } return downY >= leftUpY && downY <= rightDownY && downX >= leftUpX && downX <= rightDownX; }}
其用到的接口SwitchSlideListener:
public interface SwitchSlideListener { /** * * @param switchFlag true表示按钮打开,false表示按钮关闭 */ void onSwitchSlide(boolean switchFlag);}
onCreate处理回调结果(相当于用法):
((SwitchVerticalSlide) findViewById(R.id.control)).addSlideListener(new SwitchSlideListener() { @Override public void onSwitchSlide(boolean switchFlag) { if (switchFlag){ Toast.makeText(MainActivity.this, "打开", Toast.LENGTH_SHORT).show(); }else { Toast.makeText(MainActivity.this, "关闭", Toast.LENGTH_SHORT).show(); } }});
本人亲测有效,完全属于个人原创,没有参考任何人的代码
阅读全文
0 0
- Android-自定义滑动按钮
- android 自定义滑动按钮控件
- Android 仿 Iphone 自定义滑动按钮(SlipButton)
- android自定义滑动启动和关闭按钮
- android自定义滑动启动和关闭按钮
- Android 仿 iPhone 自定义滑动按钮
- android 自定义控件之滑动按钮
- Android开发自定义View之滑动按钮与自定义属性
- Android开发自定义View之滑动按钮与自定义属性
- 自定义滑动选择按钮
- 自定义滑动按钮
- 自定义控件--滑动按钮
- android开发之自定义Seekbar滑动条,文字跟随滑动按钮一起滑动
- Android自定义Seekbar滑动条,Pop提示跟随滑动按钮一起滑动
- Android 自定义View学习(3)--仿IOS风格滑动按钮
- Android自定义SwitchButton左右滑动开关按钮控件
- Android 自定义view的实现 滑动按钮案列
- 安卓自定义滑动按钮
- 微信小程序开发(1)----post方法与get方法的封装
- Java中Collection扩展之commons
- 二维数组 参数传递
- HDU4745环的回文串
- redis.conf的常用配置
- Android-自定义滑动按钮
- java内存区域知识点图解
- mysql中将15位身份证号改为18位
- 讨论mysql和mysqli两种连接数据库方式
- mysql创建和删除表
- JDBC之使用策略模式和模板方法模式优化代码
- Vue笔记
- Win7桌面任务栏的高度怎么调整教程 如何更改WIN7 桌面底部栏的大小
- Linux最小系统的烧写