zoukankan      html  css  js  c++  java
  • 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 }

       

          

  • 相关阅读:
    Is It A Tree?(并查集)(dfs也可以解决)
    【转】python中查询某个函数的使用方法
    python2和python3 print输出不换行
    Python在Windows下列出所有的安装包和模块
    构建打包发布模块及导入使用
    Python保存时提示“SyntaxError: Non-ASCII character 'xe8' in file”
    python基础学习(一)
    命令别名设定:alias,unalias 历史命令:history
    变量内容的删除、取代与替换(optional)
    变量键盘读取、数组与宣告:read,array,declare
  • 原文地址:https://www.cnblogs.com/mrszhou/p/6889139.html
Copyright © 2011-2022 走看看