1. 程式人生 > >自定義SlideButton(基於屬性動畫)

自定義SlideButton(基於屬性動畫)

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()。