转载

android中实现view可以滑动的六种方法

在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>

现在来运行程序。效果如下:

android中实现view可以滑动的六种方法

效果还可以吧。可以自由的滑动了。

其实上面我们用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; } 

红色部分为修改的核心代码,运行一下,效果依旧,不再贴图。

限于篇幅,请保存好这些代码,在下一篇文章中仍旧在此基础上编写。未完待续....

正文到此结束
Loading...