SlideButton主要包括一个长的滑动范围和一个可以滑动的button。滑动范围可以用一般的layout组件就可以,例如RelativeLayout,FrameLayout。
在layout组件的onTouch事件去控制button的移动范围。我最开始直接用button.layout(l,t,r,b)去控制滑动的位置,当我用属性动画ValueAnimtion时发现动画变化后,button的真实位置也就是getLeft(),….getBottom()并没有改变,导致移动button的时候出现错位现象。
网上很多关于属性动画的demo,但是这个问题却很少人提,可能不是很多人深入研究的关系。既然是属性动画,是要改变属性的,那为什么没有变化?
原来移动这个属性动画,针对的位置属性并不是layout()的值,而是两个位移值:translationX和translationY,这两个位移值就是相对于view(在这里是button)初始状态所在坐标的相对总位移。像x坐标,不管移动左边还是右边,值都是一直在累加,translationX就是总移动的距离,只要在初始点的右边都是正数,在初始点的左边都是负数。y坐标也跟x坐标相似,只要在初始点的下面都是正数,在初始点的上面都是负数。
理清这个概念,那么在onTouch事件中,触摸的移动我们也利用这个translationX,translationY的值,这样保证跟属性动画值统一。
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
break;
case MotionEvent.ACTION_MOVE:
moveX = event.getX();
float alterMove = moveX-downX;
totoalMove+=alterMove;
if(totoalMove<=0){
totoalMove = 0;
}else if(totoalMove>=getWidth()-button.getWidth()){
totoalMove=getWidth()-button.getWidth();
}
button.setTranslationX(totoalMove);
break;
case MotionEvent.ACTION_UP:
if(totoalMove<getWidth()-button.getWidth()){
startSlideAnimation();
}
break;
}
updateTips();
return false;
}
还有一个知识点,要停掉循环滚动的小标动画。
Animation提供了cancel(),pause()方法,具体看API的差异。最简单就是把动画所有者view的animation清理掉或者把动画cancel()。