在android開發中,經常會遇到一個view需要它能夠支持滑動的需求。今天就來總結實現其滑動的六種方法。其實每一種方法的
思路都是一樣的,即:監聽手勢觸摸的坐標來實現view坐標的變化,從而實現view的滑動效果。
一、通過Layout方法來實現滑動
如果你將滑動后的目標位置的坐標傳遞給Layout,這樣子就會把view的位置給重新布置了一下,在視覺上就是view的一個滑動的效果。
這就是利用Layout方法實現滑動的核心思路。我們來看一下代碼:
新建項目,然后自定義一個view,代碼如下:
1 package com.example.testdragview; 2 3 import android.content.Context; 4 import android.util.AttributeSet; 5 import android.util.Log; 6 import android.view.MotionEvent; 7 import android.view.View; 8 9 public class DragView extends View{ 10 11 12 private int lastX; 13 private int lastY; 14 15 16 public DragView(Context context, AttributeSet attrs, int defStyleAttr) { 17 super(context, attrs, defStyleAttr); 18 } 19 20 public DragView(Context context, AttributeSet attrs) { 21 super(context, attrs); 22 } 23 24 public DragView(Context context) { 25 super(context); 26 } 27 28 29 30 public boolean onTouchEvent(MotionEvent event) { 31 32 // Log.d("付勇焜----->","TouchEvent"); 33 // Log.d("付勇焜----->",super.onTouchEvent(event)+""); 34 35 36 //獲取到手指處的橫坐標和縱坐標 37 int x = (int) event.getX(); 38 int y = (int) event.getY(); 39 40 switch(event.getAction()) 41 { 42 case MotionEvent.ACTION_DOWN: 43 44 lastX = x; 45 lastY = y; 46 47 break; 48 49 case MotionEvent.ACTION_MOVE: 50 51 //計算移動的距離 52 int offX = x - lastX; 53 int offY = y - lastY; 54 //調用layout方法來重新放置它的位置 55 layout(getLeft()+offX, getTop()+offY, 56 getRight()+offX , getBottom()+offY); 57 58 break; 59 } 60 61 return true; 62 } 63 }
核心代碼就是onTouchEvent方法了。代碼很簡單,無非就是記錄手指的上次坐標與下次坐標,然后將前后移動的增量傳遞給layout方法而已。
值得注意的是,onTouchEvent的返回值為true,表示我們要成功消化掉這個觸摸事件。
然后再修改activity_main.xml的代碼,將這個view裝到布局里,如下:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 > 6 7 <com.example.testdragview.DragView 8 android:layout_width="100dp" 9 android:layout_height="100dp" 10 android:background="#FF0000" /> 11 12 </LinearLayout>
現在來運行程序。效果如下:
效果還可以吧。可以自由的滑動了。
其實上面我們用getX()和getY()獲得的是在視圖坐標系中的值。其實我們也可以使用絕對坐標,即使用getRawX()和getRawY()獲得的值
來實現這個滑動效果。修改DragView中的onTouchEvent中的代碼,如下所示:
1 public boolean onTouchEvent(MotionEvent event) { 2 3 //獲取到手指處的橫坐標和縱坐標 4 int x = (int) event.getRawX(); 5 int y = (int) event.getRawY(); 6 7 switch(event.getAction()) 8 { 9 case MotionEvent.ACTION_DOWN: 10 11 lastX = x; 12 lastY = y; 13 14 break; 15 16 case MotionEvent.ACTION_MOVE: 17 18 //計算移動的距離 19 int offX = x - lastX; 20 int offY = y - lastY; 21 //調用layout方法來重新放置它的位置 22 layout(getLeft()+offX, getTop()+offY, 23 getRight()+offX , getBottom()+offY); 24 25 lastX = x; 26 lastY = y; 27 28 break; 29 } 30 31 return true; 32 }
一定注意,此時不同的是,在move過程中,我們要及時改變lastX,與lastY的值來獲取正確的之前坐標(因為是在Android坐標系嘛,用的是絕對距離)。
此時再次運行程序,效果跟上圖一樣。
二、offsetLeftAndRight()和offsetTopAndBottom()方法來實現
其實這兩個方法分別是對左右移動和上下移動的封裝,傳入的就是偏移量。此時將DragView中的onTouchEvent代碼簡單替換即可,如下:
1 public boolean onTouchEvent(MotionEvent event) { 2 3 //獲取到手指處的橫坐標和縱坐標 4 int x = (int) event.getX(); 5 int y = (int) event.getY(); 6 7 switch(event.getAction()) 8 { 9 case MotionEvent.ACTION_DOWN: 10 11 lastX = x; 12 lastY = y; 13 14 break; 15 16 case MotionEvent.ACTION_MOVE: 17 18 //計算移動的距離 19 int offX = x - lastX; 20 int offY = y - lastY; 21 22 offsetLeftAndRight(offX); 23 offsetTopAndBottom(offY); 24 25 break; 26 } 27 28 return true; 29 }
紅色部分就是關鍵代碼了,運行一下程序,跟上面的效果是一樣的,不再貼圖。
三、使用LayoutParams來實現
依舊修改DragView的onTouchEvent代碼,如下:
1 public boolean onTouchEvent(MotionEvent event) { 2 3 //獲取到手指處的橫坐標和縱坐標 4 int x = (int) event.getX(); 5 int y = (int) event.getY(); 6 7 switch(event.getAction()) 8 { 9 case MotionEvent.ACTION_DOWN: 10 11 lastX = x; 12 lastY = y; 13 14 break; 15 16 case MotionEvent.ACTION_MOVE: 17 18 //計算移動的距離 19 int offX = x - lastX; 20 int offY = y - lastY; 21 22 ViewGroup.MarginLayoutParams mlp = 23 (MarginLayoutParams) getLayoutParams(); 24 25 mlp.leftMargin = getLeft()+offX; 26 mlp.topMargin = getTop()+offY; 27 28 setLayoutParams(mlp); 29 30 break; 31 } 32 33 return true; 34 }
紅色部分依舊是關鍵代碼。注意這里我們一般通過改變view的Margin屬性來改變其位置的。
運行程序,結果依舊,不再貼圖。
四、通過scrollTo和scrollBy方法
在一個view中,系統也提供了scrollTo和scrollBy方法來移動view。很好理解,sceollTo(x,y)傳入的應該是移動的終點坐標,而scrollBy(dx,dy)傳入的是
移動的增量。這兩個方法要在view所在的viewGroup中使用!但是一定要注意:通過scrollBy傳入的值應該是你需要的那個增量的相反數!這樣子才能達到你想
要的效果!!切記切記
依舊是hi修改DragView的onTouchEvent代碼,如下:
public boolean onTouchEvent(MotionEvent event) { //獲取到手指處的橫坐標和縱坐標 int x = (int) event.getX(); int y = (int) event.getY(); switch(event.getAction()) { case MotionEvent.ACTION_DOWN: lastX = x; lastY = y; break; case MotionEvent.ACTION_MOVE: //計算移動的距離 int offX = x - lastX; int offY = y - lastY; ((View) getParent()).scrollBy(-offX,- offY); break; } return true; }
紅色部分為修改的核心代碼,運行一下,效果依舊,不再貼圖。
限於篇幅,請保存好這些代碼,在下一篇文章中仍舊在此基礎上編寫。未完待續....
點擊下面鏈接,查看滑動的第五種方法:
http://www.cnblogs.com/fuly550871915/p/4985482.html