仿IOS SwitchButton开关滑动效果,给你丝滑般的体验

  1. 背景
  2. 效果
  3. 使用方法
  4. 原理解析

背景

由于开发中经常会用到滑动开关,但是Android自带的滑动开发滑动效果太难看,所以这里模仿了IOS的滑动效果自制了一个滑动开关.

效果

使用方法

1.style.xml中引入自定义标签
 "SwitchButton">
 "sb_shadow_radius" format="reference|dimension" />
 "sb_shadow_offset" format="reference|dimension" />
 "sb_shadow_color" format="reference|color" />
 "sb_uncheck_color" format="reference|color" />
 "sb_checked_color" format="reference|color" />
 "sb_border_width" format="reference|dimension" />
 "sb_checkline_color" format="reference|color" />
 "sb_checkline_width" format="reference|dimension" />
 "sb_uncheckcircle_color" format="reference|color" />
 "sb_uncheckcircle_width" format="reference|dimension" />
 "sb_uncheckcircle_radius" format="reference|dimension" />
 "sb_checked" format="reference|boolean" />
 "sb_shadow_effect" format="reference|boolean" />
 "sb_effect_duration" format="reference|integer" />
 "sb_button_color" format="reference|color" />
 "sb_show_indicator" format="reference|boolean" />
 "sb_background" format="reference|color" />
 "sb_enable_effect" format="reference|boolean" />
 
2.引入自定义View布局
<per.stramchen.switchbuttondemo.SwitchButton
	android:id="@+id/btn_voice_switch"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:layout_weight="1"
	app:sb_background="#E8E9EB"
	app:sb_checked_color="#65C065"
	app:sb_show_indicator="false" />
3.设置监听
        switchButton.setOnCheckedChangeListener(
        new SwitchButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(SwitchButton view, final boolean isChecked) {
           
            }
        });

4.原理解析

实现思路其实很简单,我们可以将按钮的状态变换分为两种情况.
1.手动拖拽改变按钮位置.
2.点击使按钮自动滑动到另一端.

1.手动拖拽改变按钮位置.

对于第一种情况的实现其实很容易,我们只需要用手指移动的距离来改变滑块的位置,以及背景色的深浅即可.当然这需要我们手动拦截View的touch事件.以下贴出关键代码.
fraction我们可以理解为变化率,就是手指划过的距离占整个控件的百分比,接下来我们利用fraction来计算出button的X坐标,下面的buttonMaxX-buttonMinX我们可以理解为SwitchButton的真实长度.然后我们利用argbEvaluator这样一个颜色估值器来拿到不同时刻的变化率的颜色值,将它赋给背景色.最后调用postInvalidate();来刷新UI,我们就可以达到用手滑的时候,颜色随之改变的效果了.

//……………………………………部分代码省略
case MotionEvent.ACTION_MOVE:{
//拖动按钮位置,同时改变对应的背景颜色
float fraction = eventX / getWidth();
//变化率
fraction = Math.max(0f, Math.min(1f, fraction));
//滑块的位置
viewState.buttonX = buttonMinX
                   + (buttonMaxX - buttonMinX)
                   * fraction;
//背景色
viewState.checkStateColor = (int) argbEvaluator.evaluate(
                            fraction,
                            uncheckColor,
                            checkedColor);
postInvalidate();
}
//……………………………………部分代码省略
2.点击使按钮自动滑动到另一端

这个实现起来其实也很方便,我们只需要利用一个属性动画,即可解决问题.
那么第一步我们需要判断它是否是一个点击时间,由于我们拦截了整个touch事件,那么点击事件的判断需要我们自己来完成,我们可以用一次按下抬起的时间小于300ms来判断它是否是一次点击事件

if(System.currentTimeMillis() - touchDownTime <= 300){
                    //点击时间小于300ms,认为是点击操作
                    toggle();
                }

如果是点击事件,我们就可以开启动画来让滑块自己滑动来.这里我们并没有使用ObjectAnimator,而是使用的是ValueAnimator,因为这样可以让我们在每一帧改变多个属性.下面展示关键代码.
实现方式,其实与上面也很类似,只不过这时候我们改变属性的时刻不是在touch的时候了,而且在ValueAnimator每一帧的回调里.同样是计算button的X坐标,背景色,以及变化半径.

@Override
//……………………………………部分代码省略
public void onAnimationUpdate(ValueAnimator animation) {
//……………………………………部分代码省略
viewState.buttonX = beforeState.buttonX
                  + (afterState.buttonX - beforeState.buttonX) * value;

float fraction = (viewState.buttonX - buttonMinX) / (buttonMaxX - buttonMinX);

viewState.checkStateColor = (int) argbEvaluator.evaluate(
                            fraction,
                            uncheckColor,
                            checkedColor
                    );

viewState.radius = fraction * viewRadius;
                    );
postInvalidate();
//……………………………………部分代码省略
}

当然,真实场景要比理论稍微复杂一些,我们需要考虑一些特殊的情况,比如在自动滑动的时候,我们突然点击了滑块,我们该怎么处理.等等.这里就不详细展开了.读者可以阅读源码自行探索.

下面贴出源码以及demo地址,
https://github.com/stramChen/SwitchButton

如果任何疑问,请联系邮箱:[email protected]

你可能感兴趣的:(技术类,Android,android,java)