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

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

     

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

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

  • 相关阅读:
    亚马逊云IoT平台接入开发记录
    pip下载速度慢更换清华源试试
    gitlab回归上一次提交
    uos桌面壁纸存放路径
    python中json中的dump和dumps
    Python中的类中__dict__方法
    C++ | 数组反转的三种方法
    《C++Primer Plus》 | 复合类型
    pwn 中的函数 | 持续更新
    七月安恒DASCTF | 复现
  • 原文地址:https://www.cnblogs.com/fuly550871915/p/4985053.html
Copyright © 2011-2022 走看看