ViewDragHelper

来源:互联网 发布:淘宝商品描述图片尺寸 编辑:程序博客网 时间:2024/04/28 23:06

版权声明:本文为博主原创文章,未经博主允许不得转载。
目录(?)[+]
转载请标明出处:
http://blog.csdn.net/lmj623565791/article/details/46858663;
本文出自:【张鸿洋的博客】
一、概述

在自定义ViewGroup中,很多效果都包含用户手指去拖动其内部的某个View(eg:侧滑菜单等),针对具体的需要去写好onInterceptTouchEvent和onTouchEvent这两个方法是一件很不容易的事,需要自己去处理:多手指的处理、加速度检测等等。
好在官方在v4的支持包中提供了ViewDragHelper这样一个类来帮助我们方便的编写自定义ViewGroup。简单看一下它的注释:

ViewDragHelper is a utility class for writing custom ViewGroups. It offers a number
of useful operations and state tracking for allowing a user to drag and reposition
views within their parent ViewGroup.
本篇博客将重点介绍ViewDragHelper的使用,并且最终去实现一个类似DrawerLayout的一个自定义的ViewGroup。(ps:官方的DrawerLayout就是用此类实现)

二、入门小示例

首先我们通过一个简单的例子来看看其快捷的用法,分为以下几个步骤:

创建实例
触摸相关的方法的调用
ViewDragHelper.Callback实例的编写
(一) 自定义ViewGroup

package com.zhy.learn.view;

import android.content.Context;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;

/**
* Created by zhy on 15/6/3.
*/
public class VDHLayout extends LinearLayout
{
private ViewDragHelper mDragger;

public VDHLayout(Context context, AttributeSet attrs){    super(context, attrs);    mDragger = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback()    {        @Override        public boolean tryCaptureView(View child, int pointerId)        {            return true;        }        @Override        public int clampViewPositionHorizontal(View child, int left, int dx)        {            return left;        }        @Override        public int clampViewPositionVertical(View child, int top, int dy)        {            return top;        }    });}

@Override
public boolean onInterceptTouchEvent(MotionEvent event)
{
return mDragger.shouldInterceptTouchEvent(event);
}

@Overridepublic boolean onTouchEvent(MotionEvent event){    mDragger.processTouchEvent(event);    return true;}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
可以看到,上面整个自定义ViewGroup的代码非常简洁,遵循上述3个步骤:

1、创建实例

mDragger = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback()
{
});
1
2
3
1
2
3
创建实例需要3个参数,第一个就是当前的ViewGroup,第二个sensitivity,主要用于设置touchSlop:

helper.mTouchSlop = (int) (helper.mTouchSlop * (1 / sensitivity));
1
1
可见传入越大,mTouchSlop的值就会越小。第三个参数就是Callback,在用户的触摸过程中会回调相关方法,后面会细说。

2、触摸相关方法

@Override
public boolean onInterceptTouchEvent(MotionEvent event)
{
return mDragger.shouldInterceptTouchEvent(event);
}

@Overridepublic boolean onTouchEvent(MotionEvent event){    mDragger.processTouchEvent(event);    return true;}

1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
onInterceptTouchEvent中通过使用mDragger.shouldInterceptTouchEvent(event)来决定我们是否应该拦截当前的事件。onTouchEvent中通过mDragger.processTouchEvent(event)处理事件。

3、实现ViewDragHelper.CallCack相关方法

new ViewDragHelper.Callback()
{
@Override
public boolean tryCaptureView(View child, int pointerId)
{
return true;
}

        @Override        public int clampViewPositionHorizontal(View child, int left, int dx)        {            return left;        }        @Override        public int clampViewPositionVertical(View child, int top, int dy)        {            return top;        }    }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ViewDragHelper中拦截和处理事件时,需要会回调CallBack中的很多方法来决定一些事,比如:哪些子View可以移动、对个移动的View的边界的控制等等。

上面复写的3个方法:

tryCaptureView如何返回ture则表示可以捕获该view,你可以根据传入的第一个view参数决定哪些可以捕获
clampViewPositionHorizontal,clampViewPositionVertical可以在该方法中对child移动的边界进行控制,left , top 分别为即将移动到的位置,比如横向的情况下,我希望只在ViewGroup的内部移动,即:最小>=paddingleft,最大<=ViewGroup.getWidth()-paddingright-child.getWidth。就可以按照如下代码编写:
@Override
public int clampViewPositionHorizontal(View child, int left, int dx)
{
final int leftBound = getPaddingLeft();
final int rightBound = getWidth() - mDragView.getWidth() - leftBound;

            final int newLeft = Math.min(Math.max(left, leftBound), rightBound);            return newLeft;        }

1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
经过上述3个步骤,我们就完成了一个简单的自定义ViewGroup,可以自由的拖动子View。

简单看一下布局文件

(二) 布局文件

0 0
原创粉丝点击