android中實現view可以滑動的六種方法續篇(一)


     承接上一篇,如果你沒有讀過前四章方法,可以點擊下面的鏈接:

http://www.cnblogs.com/fuly550871915/p/4985053.html

     下面開始講第五中方法。

 

五、利用Scroller類實現滑動

 

(1)基礎知識總結

      為了便於下面的閱讀代碼,先來總結一下關於Scroller類的基礎知識。利用Scroller類實現滑動,需要三個步驟:

 

步驟一:
初始化Scroller對象,即mScroller = new Scroller(context)
步驟二:
重寫computeScroll()方法,實現模擬滑動。可以復制下面的末模板代碼:
public void computeScroll() {
            super.computeScroll();
            
            if(mScroller.computeScrollOffset())
            {
                ((View)getParent()).scrollTo(mScroller.getCurrX(),
                        mScroller.getCurrY());
            }
            
            invalidate();//必須要調用
        }

 

步驟三:
開啟模擬過程,在合適的地方(一般都在move中)startScroll方法。它有兩個重載方法如下:
startScroll(int startX,int startY, int dx,int dy,int duration)
startScroll(int startX,int startY,int dx,int dy)
方法中的參數無需多解釋了,就是起始坐標與偏移量,還有完成偏移的時間而已。

 

 

 

        需要說明的是:(1)computeScrollOffset方法用來判斷是否完成了整個滑動,返回為true,則說明沒有完成,否則則完成滑動。

                            (2)getCurrY以及getCurrX獲得的是當前的滑動坐標。

                            (3)最后必須要用invalidate方法來刷新。因為computeScroll方法不會自動調用,是在draw方法中被調用的。所以

                                   必須使用invalidate刷新,就會調用draw方法,自然就會調用computeScroll方法了。這樣子就會實現循環調用。

                            (4)在startScroll中,偏移量跟使用scrollBy方法中的偏移量用法是一樣的,即也必須填寫你實際想要移動距離的相

                                   反數。也就是你實際想讓它偏移一個正值,這里就填寫它相應的負值,如果想偏移一個負值,這里就填寫相應的

                                   正值!

(2)代碼實踐

       有些東西還是需要在真正的代碼中才能說的明白的。我們接着上一篇文章的代碼繼續編寫。為了看清Scroller類是如何實現滑動的,我們

再次修改DragView的代碼。這次修改的有些多。貼完整的代碼出來。如下:

 1 package com.example.testdragview;
 2 
 3 import android.content.Context;
 4 import android.util.AttributeSet;
 5 import android.view.MotionEvent;
 6 import android.view.View;
 7 import android.widget.Scroller;
 8 
 9 public class DragView extends View{
10     
11     
12     private int lastX;
13     private int lastY;
14     private Scroller mScroller;
15 
16     public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
17         super(context, attrs, defStyleAttr);
18         
19         mScroller = new Scroller(context);
20     }
21 
22     public DragView(Context context, AttributeSet attrs) {
23         super(context, attrs);
24         mScroller = new Scroller(context);
25     }
26 
27     public DragView(Context context) {
28         super(context);
29         mScroller = new Scroller(context);
30     }
31 
32     
33     
34     public boolean onTouchEvent(MotionEvent event) {
35         
36         //獲取到手指處的橫坐標和縱坐標
37         int x = (int) event.getX();
38         int y = (int) event.getY();
39         
40         
41         switch(event.getAction())
42         {
43         case MotionEvent.ACTION_DOWN:
44             
45             lastX = x;
46             lastY = y;
47             break;
48             
49         case MotionEvent.ACTION_MOVE:
50             
51             //計算移動的距離
52             int offX = x - lastX;
53             int offY = y - lastY;
54             
55             View viewGroup = (View) getParent();
56             
57             //開啟滑動
58             mScroller.startScroll(viewGroup.getScrollX(),
59                     viewGroup.getScrollY(), -offX, -offY);
60         
61             break;
62             
63         case MotionEvent.ACTION_UP:
64             
65             break;
66         }
67         return true;
68     }
69     
70     
71     
72         public void computeScroll() {
73             super.computeScroll();
74             
75             if(mScroller.computeScrollOffset())
76             {
77                 ((View)getParent()).scrollTo(mScroller.getCurrX(),
78                         mScroller.getCurrY());
79             }
80             
81             invalidate();//必須要調用
82         }
83 }

 

     紅色部分就是修改的核心代碼了。需要說明的是,在開啟滑動的代碼中,即第58行,使用的是在父視圖中使用getScrollX和getScrollY獲取

所滑動到的點的坐標。而getScollX和getScrollY正是從computeScroll中的scrollTo方法中傳遞過來的。通過閱讀源碼你可以很清晰的看到這個

過程。我貼兩張源碼圖吧,如下:

                               

       上圖中觀察mScrollX的傳遞過程,確實如上面我所說的。

       而且在開啟滑動的代碼中,注意我們將偏移量可是都設定為負值了哦!(正如我上面所講的設定為相反數即可)。

       好了,關於代碼的解釋,就講這么多,其他的都很好理解了。現在就運行程序,效果如下:

 

     值得注意的是,我們的的DragView(即紅色的塊塊)並不是即時跟隨鼠標的滑動,在真機上這個效果將會更加突出!!其實這就是

Scrollerl類的滑動特點!即手指到達某一位置后,view會隨后再平滑的到達這個位置,也就是說並不是view和手指一起到達指定位置的。

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

      因此,一般並不利用Scroller類實現滑動,因為它不是即時的。但卻經常用它來實現手指抬起后,view回到初始位置!

      來修改下DragView看看怎么實現這個效果。代碼如下:

 1 package com.example.testdragview;
 2 
 3 import android.content.Context;
 4 import android.util.AttributeSet;
 5 import android.view.MotionEvent;
 6 import android.view.View;
 7 import android.widget.Scroller;
 8 
 9 public class DragView extends View{
10     
11     
12     private int lastX;
13     private int lastY;
14     private Scroller mScroller;
15 
16     public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
17         super(context, attrs, defStyleAttr);
18         
19         mScroller = new Scroller(context);
20     }
21 
22     public DragView(Context context, AttributeSet attrs) {
23         super(context, attrs);
24         mScroller = new Scroller(context);
25     }
26 
27     public DragView(Context context) {
28         super(context);
29         mScroller = new Scroller(context);
30     }
31 
32     
33     
34     public boolean onTouchEvent(MotionEvent event) {
35         
36         //獲取到手指處的橫坐標和縱坐標
37         int x = (int) event.getX();
38         int y = (int) event.getY();
39         
40         
41         switch(event.getAction())
42         {
43         case MotionEvent.ACTION_DOWN:
44             
45             lastX = x;
46             lastY = y;
47             break;
48             
49         case MotionEvent.ACTION_MOVE:
50             
51             //計算移動的距離
52             int offX = x - lastX;
53             int offY = y - lastY;
54             
55              ((View) getParent()).scrollBy(-offX,- offY);
56 
57             break;
58             
59         case MotionEvent.ACTION_UP:
60             
61             View viewGroup = (View) getParent();
62             
63             //開啟滑動,讓其回到原點
64             mScroller.startScroll(viewGroup.getScrollX(),
65                     viewGroup.getScrollY(),
66                     -viewGroup.getScrollX() ,-viewGroup.getScrollY() );
67             
68             break;
69         }
70         return true;
71     }
72     
73     
74     
75         public void computeScroll() {
76             super.computeScroll();
77             
78             if(mScroller.computeScrollOffset())
79             {
80                 ((View)getParent()).scrollTo(mScroller.getCurrX(),
81                         mScroller.getCurrY());
82             }
83             
84             invalidate();//必須要調用
85         }
86 }

 

      紅色部分依舊是修改的核心代碼。這里主要就是將實現的滑動效果替換成了用scrollBy來實現即時滑動,然后在手指抬起的up方法中,利用

Scoller類將view放回原來位置!運行一下,看看效果,如下:

     如上圖所示,只要鼠標一抬起,紅色塊塊就會立刻回到原來位置!怎么樣不錯吧。

 

 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

好了,關於這個Scroller類的使用,就講到這里。上面的代碼基本都可以當做是模板代碼了,需要的時候過來看看復制一下吧。

未完待續.....(最后一種方法)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM