Android中View滑動實現方式
滑動作為Android中最基礎的特效之一,使用場景非常廣泛。實現的方式也有多種,理解各種滑動的實現方式。清楚在開發中根據自己的實際需求,選擇合理的實現方案。這篇文章從:scrollTo()/scrollBy()內容滑動|動畫方式滑動|修改布局參數,三種方式來做簡要的分析。
一丶scrollerTo()&&scrollBy()內容滑動
這兩個方法都是View自帶的滑動方法,即每個控件都可以通過調用這兩個方法實現滑動。scrollBy()方法的實現本質也是調用scrollTo()方法,不同之處在於。scrollyTo()方法參數是確定滑動位置的終點,即要滑動到哪兒去,絕對坐標。而scrollBy()方法參數是形容要滑動的距離,要滑動多少,根據當前位置的相對坐標。 下面通過源碼來一探究竟:
public void scrollTo(int x, int y) {
if (mScrollX != x || mScrollY != y) {
int oldX = mScrollX;
int oldY = mScrollY;
mScrollX = x;
mScrollY = y;
invalidateParentCaches();
onScrollChanged(mScrollX, mScrollY, oldX, oldY);
if (!awakenScrollBars()) {
postInvalidateOnAnimation();
}
}
}
public void scrollBy(int x, int y) {
scrollTo(mScrollX + x, mScrollY + y);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
從源碼中可以得知scrollTo()方法會先判斷起點和終點的位置是否不相同,符合滑動的條件,保存和更新起點坐標,不難理解滑動後終點就成了新的起點。這樣就造成了此次滑動完成後,再調用次方法,如果參數終點坐標和起點坐標相同,滑動就不會生效。而scrollBy()方法中直接調用scrollTo方法,將起點坐標位置和滑動的距離相加,確定終點位置,這樣終點坐標永遠都不會和起點坐標重復,滑動一直有效。舉個栗子:
scrollTo()效果 btn_scroll.scrollTo(100,0)
怎麽按鈕沒動,字怎麽動了?沒錯,scrollTo()方法是對View的內容進行滑動,調用Button的scrollTo()方法滑動的是他的字,TextView也是這樣,當然Button本質也是基於TextView。當自定義View時,滑動的就是裏面的圓丶矩形丶view…… 當Button跑了100像素時,再點擊執行scrollTo(100,0)時就沒有任何反應了,這就是相對起點的絕對坐標。
scrollBy()效果: btn_scroll.scrollBy(100,0);
一直執行scrollBy(100,0)都是生效的,這就是相對當前位置的相對坐標。結論:scrollTo()和scrollBy()這兩種方法是對View的內容進行滑動,並沒有改變View真正的布局位置。
二丶動畫方式實現滑動
動畫方式主要有兩種補間動畫和屬性動畫,這兩種方式也沒有實際改變view布局位置,需要值得註意的是補間動畫執行結束後效果會瞬間回到原來的位置,是對影像進行操作,將fillAfter屬性改為true就不會有這種效果,屬性動畫則沒有這一特性。舉個栗子:
/*補間動畫*/
TranslateAnimation animation = new TranslateAnimation(0,300,0,0);
animation.setDuration(2000);
animation.setFillAfter(true);
btn_scroll.startAnimation(animation);
/*屬性動畫*/
ObjectAnimator animator = ObjectAnimator.ofFloat(btn_scroll,"translationX",0,300);
animator.setDuration(2000).start();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
實現效果:
而補間動畫還會有一個問題,當Button滑動完成之後,再點擊Button沒有任何響應,而點擊Button之前的位置仍可以觸發onClick()事件,屬性動畫沒有這一特性。
三丶修改布局參數
前面講到的兩種方式都提到並沒有真正改變布局參數,這回終於說到改變布局參數而實現。。這種方式是直接改變View在父view中的布局位置,比如要實現上圖Button右滑300像素,則將View左邊到父View左邊的距離Left,View右邊到父View左邊的距離Right增加300px(對視圖坐標系不太清楚的可以參考這篇文章:坐標系),即可實現,舉個栗子:
btn_scroll.layout(btn_scroll.getLeft()+300,btn_scroll.getTop(),btn_scroll.getRight()+300,btn_scroll.getBottom());
- 1
效果和上圖動畫實現大致相同,不同在於動畫可以規定在多長時間內完成滑動,而修改布局參數和scrollTo()/scrollBy()方法都是在瞬間完成的!修改布局參數的實現方式有多種,但是原理都是一樣的就不一 一說明了。
各種方式比較
這裏就直接摘錄引用《Android開發藝術探索》中的,大佬總結的比較到位。
閱讀全文先看scrollTo/scrollBy這種方式.它是View提供的原生方法,其作用是專門用於View的滑動,它可以比較簡單的實現滑動效果,並且不影響內部元素的單擊事件.但是它的缺點也是很顯然的,它只能滑動View的內容,不能滑動View本身。
再看動畫,通過動畫來實現View的滑動,這要分情況.如果是Android3.0以上並采用屬性動畫,那麽采用這種方式沒有明顯的缺點;如果說是使用View動畫或者在Android3.0以下使用屬性動畫,均不能改變View本身的屬性.在實際使用中,如果動畫元素不需要響應用戶的交互,那麽使用動畫來做滑動是比較適合的,否則就不太適合.但是動畫有一個明顯的優點,那就是一些復雜的效果必須通過動畫才能實現.。
最後看一下改變布局的這種方式,它除了使用起來麻煩點之外,也沒有明顯的缺點,它的主要使用對象是一些具有交互性的View,因為這些View需要和用戶交互,直接通過動畫實現會有問題.所以這個時候我們需要使用直接改變布局參數的方法去實現。
scrollTo/scrollBy:操作簡單,適合對View內容的滑動。
動畫:操作簡單,主要使用於沒有交互的View和實現復雜的動畫效果。
改變布局參數:操作稍微復雜,適用於有交互的View。
Android中View滑動實現方式