Androin学习笔记五十三: Android中实现view可以滑动的六种方法

出处:http://www.linuxidc.com/Linux/2015-11/125390.htm

Android开发中,经常会遇到一个view需要它能够支持滑动的需求。今天就来总结实现其滑动的六种方法。其实每一种方法的思路都是一样的,即:监听手势触摸的坐标来实现view坐标的变化,从而实现view的滑动效果。

一、通过Layout方法来实现滑动

如果你将滑动后的目标位置的坐标传递给Layout,这样子就会把view的位置给重新布置了一下,在视觉上就是view的一个滑动的效果。

这就是利用Layout方法实现滑动的核心思路。我们来看一下代码:

新建项目,然后自定义一个view,代码如下:

package com.example.testdragview;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class DragView extends View{
    
    
    private int lastX;
    private int lastY;
   

    public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public DragView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public DragView(Context context) {
        super(context);
    }

    
    
    public boolean onTouchEvent(MotionEvent event) {
        
//        Log.d("付勇焜----->","TouchEvent");
//        Log.d("付勇焜----->",super.onTouchEvent(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;
            //调用layout方法来重新放置它的位置
            layout(getLeft()+offX, getTop()+offY,
                    getRight()+offX    , getBottom()+offY);
        
            break;
        }
        
        return true;
    }
}

核心代码就是onTouchEvent方法了。代码很简单,无非就是记录手指的上次坐标与下次坐标,然后将前后移动的增量传递给layout方法而已。

值得注意的是,onTouchEvent的返回值为true,表示我们要成功消化掉这个触摸事件。

然后再修改activity_main.xml的代码,将这个view装到布局里,如下:

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

    <com.example.testdragview.DragView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="#FF0000" />

</LinearLayout>

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

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

其实上面我们用getX()和getY()获得的是在视图坐标系中的值。其实我们也可以使用绝对坐标,即使用getRawX()和getRawY()获得的值

来实现这个滑动效果。修改DragView中的onTouchEvent中的代码,如下所示:

 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>

一定注意,此时不同的是,在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;
    }

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值