View的滑动原理和多种滑动方法

参考链接:

http://blog.csdn.net/chunqiuwei/article/details/50679568#

http://blog.csdn.net/zly921112/article/details/50436538

view滑动种类:

 1.根据layout()方法来产生滑动

     xml代码 (下面的布局也是这个一样的)  

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">


    <study.view.com.viewstudy.DragView
        android:id="@+id/dv"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:background="#000" />


</LinearLayout>

java部分(包含计算出偏移量)

 1 package study.view.com.viewstudy;
 2 
 3 import android.content.Context;
 4 import android.util.AttributeSet;
 5 import android.view.MotionEvent;
 6 import android.view.View;
 7 
 8 
 9 public class DragView extends View {
10 
11 
12     public DragView(Context context) {
13         this(context, null);
14     }
15 
16     public DragView(Context context, AttributeSet attrs) {
17         this(context, attrs, 0);
18     }
19 
20     public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
21         super(context, attrs, defStyleAttr);
22         init(context);
23     }
24 
25     private void init(Context context) {
26     }
27 
28 
29     private int startX;
30     private int startY;
31 
32     @Override
33     public boolean onTouchEvent(MotionEvent event) {
34         int x = (int) event.getX();//表示相对于当前View的x
35         int y = (int) event.getY();//表示相对于当前View的y
36         switch (event.getAction()) {
37             /**
38              *
39              MotionEvent中的方法
40              getX()获取点击位置距离当前View左边的距离
41              getY()获取点击位置距离当前View上边的距离
42              getRawX()获取点击位置距离屏幕左边的距离
43              getRawY()获取点击位置距离屏幕上边的距离
44              */
45             case MotionEvent.ACTION_DOWN:
46                 startX = x;
47                 startY = y;
48                 break;
49             case MotionEvent.ACTION_MOVE:
50                 int distanceX = x - startX;
51                 int distanceY = y - startY;
52                 /**
53                  layout()中的方法
54                  getTop()获取到的是View自身顶边到父布局顶边的距离
55                  getBottom()获取到的是View自身底边到父布局顶边的距离
56                  getLeft()获取到的是View自身左边到父布局左边的距离
57                  getRight()获取到的是View自身右边到父布局左边的距离
58                  */
59                 layout(
60                         getLeft()+distanceX,
61                         getTop()+distanceY,
62                         getRight()+distanceX,
63                         getBottom()+distanceY
64                 );
65                 break;
66             case MotionEvent.ACTION_UP:
67 
68 
69                 break;
70         }
71         return true;
72     }
73 
74 
75 }

     2.offsetLeftAndRight(),offsetTopAndBottom()实现

      计算出偏移量后只需要下面代码即可

        

offsetLeftAndRight(distanceX);
offsetTopAndBottom(distanceY);

   3.view本身是不滑动的,滑动的是view的内容。view利用其view类内自带的方法scrollTo和ScrollBy来实现滑动

     scrollTo()移动到某点,scrollBy()移动的偏移量 (把View位置看成固定的,内容移动,并且他的坐标系正好跟我们平时的坐标系相反)

 1 public void scrollTo(int x, int y) {  
 2     if (mScrollX != x || mScrollY != y) {  
 3         int oldX = mScrollX;  
 4         int oldY = mScrollY;  
 5          //记录滑动的位置  
 6          mScrollX = x;  
 7         mScrollY = y;  
 8         invalidateParentCaches();  
 9         onScrollChanged(mScrollX, mScrollY, oldX, oldY);  
10         if (!awakenScrollBars()) {  
11             postInvalidateOnAnimation();  
12         }  
13     }  
14 }  
15   
16 public void scrollBy(int x, int y) {  
17     scrollTo(mScrollX + x, mScrollY + y);  

     java部分

     

 1 package study.view.com.viewstudy;
 2 
 3 import android.content.Context;
 4 import android.util.AttributeSet;
 5 import android.view.MotionEvent;
 6 import android.view.View;
 7 
 8 
 9 public class DragView extends View {
10 
11 
12     public DragView(Context context) {
13         this(context, null);
14     }
15 
16     public DragView(Context context, AttributeSet attrs) {
17         this(context, attrs, 0);
18     }
19 
20     public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
21         super(context, attrs, defStyleAttr);
22         init(context);
23     }
24 
25     private void init(Context context) {
26     }
27 
28 
29     private int startX;
30     private int startY;
31 
32     @Override
33     public boolean onTouchEvent(MotionEvent event) {
34         int x = (int) event.getX();//表示相对于当前View的x
35         int y = (int) event.getY();//表示相对于当前View的y
36         switch (event.getAction()) {
37             /**
38              *
39              MotionEvent中的方法
40              getX()获取点击位置距离当前View左边的距离
41              getY()获取点击位置距离当前View上边的距离
42              getRawX()获取点击位置距离屏幕左边的距离
43              getRawY()获取点击位置距离屏幕上边的距离
44              */
45             case MotionEvent.ACTION_DOWN:
46                 startX = x;
47                 startY = y;
48                 break;
49             case MotionEvent.ACTION_MOVE:
50                 int distanceX = x - startX;
51                 int distanceY = y - startY;
52                 //修改的地方
53                 ((View)getParent()).scrollBy(-distanceX,-distanceY);
54                 break;
55             case MotionEvent.ACTION_UP:
56 
57 
58                 break;
59         }
60         return true;
61     }
62 
63 
64 }

     4.利用动画,让view产生滑动效果

     java代码部分

     

 1 package study.view.com.viewstudy;
 2 
 3 import android.animation.ObjectAnimator;
 4 import android.support.v7.app.AppCompatActivity;
 5 import android.os.Bundle;
 6 import android.view.View;
 7 import android.widget.Button;
 8 import android.widget.TextView;
 9 
10 public class MainActivity extends AppCompatActivity {
11 
12     @Override
13     protected void onCreate(Bundle savedInstanceState) {
14         super.onCreate(savedInstanceState);
15         setContentView(R.layout.activity_main);
16 
17         Button bt = (Button) findViewById(R.id.bt);
18         final TextView tv = (TextView) findViewById(R.id.tv);
19         bt.setOnClickListener(new View.OnClickListener() {
20             @Override
21             public void onClick(View v) {
22                 ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(tv,"translationX",300);
23                 objectAnimator.setDuration(2000).start();
24 
25 
26             }
27         });
28     }
29 }

  xml部分

    

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:tools="http://schemas.android.com/tools"
 4     android:layout_width="match_parent"
 5     android:layout_height="match_parent"
 6     android:gravity="center"
 7     android:orientation="vertical"
 8     tools:context=".MainActivity">
 9 
10     <TextView
11         android:id="@+id/tv"
12         android:layout_width="200dp"
13         android:layout_height="200dp"
14         android:background="#f00" />
15 
16     <Button
17         android:id="@+id/bt"
18         android:layout_width="wrap_content"
19         android:layout_height="wrap_content"
20         android:text="点我" />
21 
22 </LinearLayout>

      

5.通过动态的修改LayoutParams的margin等属性让View来产生滑动

    计算出偏移量(下面有计算代码)

     

LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) getLayoutParams();
lp.topMargin = getTop()+distanceY;
lp.leftMargin = getLeft() + distanceX;
setLayoutParams(lp);

  

   

      6.Scroller实现(Scroller是将一次较长的滑动,按一定时间分成多次较小的滑动实现视觉上的弹性滑动)

     基于上面代码

     

 1 package study.view.com.viewstudy;
 2 
 3 import android.annotation.SuppressLint;
 4 import android.content.Context;
 5 import android.util.AttributeSet;
 6 import android.view.MotionEvent;
 7 import android.view.View;
 8 import android.widget.Scroller;
 9 import android.widget.TextView;
10 
11 
12 @SuppressLint("AppCompatCustomView")
13 public class DragView extends TextView {
14 
15 
16     private Scroller scroller;
17 
18     public DragView(Context context) {
19         this(context, null);
20     }
21 
22     public DragView(Context context, AttributeSet attrs) {
23         this(context, attrs, 0);
24     }
25 
26     public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
27         super(context, attrs, defStyleAttr);
28         init(context);
29     }
30 
31     private void init(Context context) {
32         scroller = new Scroller(context);
33     }
34 
35     @Override
36     public void computeScroll() {
37         super.computeScroll();
38         if(scroller.computeScrollOffset()){
39             ((View)getParent()).scrollTo(scroller.getCurrX(),scroller.getCurrY());
40             invalidate();//这里不断的递归修改坐标形成视觉上的弹性滑动
41         }
42     }
43 
44     private int startX;
45     private int startY;
46 
47     @Override
48     public boolean onTouchEvent(MotionEvent event) {
49         int x = (int) event.getX();//表示相对于当前view的x
50         int y = (int) event.getY();
51         switch (event.getAction()) {
52             case MotionEvent.ACTION_DOWN:
53                 startX = x;
54                 startY = y;
55                 break;
56             case MotionEvent.ACTION_MOVE:
57                 int distanceX = x - startX;
58                 int distanceY = y - startY;
59                 ((View)getParent()).scrollBy(-distanceX, -distanceY);
60 
61 
62 
63                 break;
64             case MotionEvent.ACTION_UP:
65                 View parent = (View) getParent();
66                 scroller.startScroll(
67                         parent.getScrollX(),
68                         parent.getScrollY(),
69                         -parent.getScrollX(),
70                         -parent.getScrollY());
71                 invalidate();//这里调用了就会触发ondraw()然后会调用computeScroll()方法
72                 break;
73         }
74         return true;
75     }
76 
77 
78 }

   

      

原文地址:https://www.cnblogs.com/mrszhou/p/6889139.html