Android之ViewDragHelper的使用
来源:互联网 发布:网络聊天用语段子 编辑:程序博客网 时间:2024/04/28 21:20
Android之ViewDragHelper的使用
关于ViewDragHelper
官方文档的介绍是:
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.
这段话很容易理解,不重复啰嗦了。
实例
使用步骤:
1.使用ViewDragHelper的静态方法create创建,需要传人一个ViewDragHelper.CallBack对象;
2.实现ViewDragHelper.CallBack中的方法,来实现对视图的一些操作,如拖拽等
3.onInterceptTouchEvent和onTouchEvent回调ViewDragHelper中对应方法
下面通过实例来简单了解一下一些主要方法的使用:
- tryCaptureView
- clampViewPositionHorizontal
- clampViewPositionVertical
- onEdgeDragStarted
- onViewReleased
- getViewHorizontalDragRange/getViewVerticalDragRange
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?><c.viewdraghpdemo.ViewDrag xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="16dp" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="c.viewdraghpdemo.MainActivity"> <TextView android:layout_width="150dp" android:layout_height="150dp" android:text="Hello World!" android:background="@android:color/holo_blue_dark"/></c.viewdraghpdemo.ViewDrag>
自定义的View
package c.viewdraghpdemo;import android.content.Context;import android.support.v4.widget.DrawerLayout;import android.support.v4.widget.ViewDragHelper;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;/** * Created by Administrator on 2016/9/26. */public class ViewDrag extends LinearLayout { private static final String TAG = "hly"; private ViewDragHelper mViewDrag; private TextView tv; public ViewDrag(Context context) { super(context, null); } public ViewDrag(Context context, AttributeSet attrs) { super(context, attrs); init(); } public ViewDrag(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { //Step1:使用静态方法构造ViewDragHelper,其中需要传入一个ViewDragHelper.Callback回调对象. mViewDrag = ViewDragHelper.create(this, 1.0f, mViewDragCB); //setEdgeTrackingEnabled设置的边界滑动时触发 mViewDrag.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT); } ViewDragHelper.Callback mViewDragCB = new ViewDragHelper.Callback() { @Override public boolean tryCaptureView(View child, int pointerId) { //返回ture则表示可以捕获该view return true; } @Override public int clampViewPositionHorizontal(View child, int left, int dx) { //手指触摸移动时实时回调, left就是child.getLeft()的值 return left; } @Override public int clampViewPositionVertical(View child, int top, int dy) { //同理 return top; } }; //重写onInterceptTouchEvent回调ViewDragHelper中对应的方法. @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return mViewDrag.shouldInterceptTouchEvent(ev); } //重写onTouchEvent回调ViewDragHelper中对应的方法. @Override public boolean onTouchEvent(MotionEvent event) { mViewDrag.processTouchEvent(event); return true; } //得到child实例 @Override protected void onFinishInflate() { tv = (TextView) getChildAt(0); }}
相关方法的用处已经在代码里注释了,应该很好理解
MainActivity.java
package c.viewdraghpdemo;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }}
简单运行一下,看看效果:
可以看见现在TextView可以被拖动了,但是这里发现可以被拖到屏幕外面,这时候就要在ViewDragHelper.CallBack里面处理一下了,具体修改如下:
@Override //手指触摸移动时实时回调, left就是child.getLeft()的值 public int clampViewPositionHorizontal(View child, int left, int dx) { //可左右滑动的空间 int spaceX = getWidth() - getPaddingRight() - child.getWidth(); return Math.min(Math.max(getPaddingLeft(), left), spaceX); } @Override public int clampViewPositionVertical(View child, int top, int dy) { //同理 int spaceY = getHeight() - getPaddingBottom() - child.getHeight(); return Math.min(Math.max(getPaddingTop(), top), spaceY); } };
运行一下,发现不会移动到屏幕外了:
在上面的代码里面还有一句
mViewDrag.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
这个是滑动到边界的时候触发的,还需要在CallBack中实现一个方法
@Override public void onEdgeDragStarted(int edgeFlags, int pointerId) { //当tryCaptureView为false时也可以生效 mViewDrag.captureChildView(tv, pointerId); }
具体效果: ![这里写图片描述](http://img.blog.csdn.net/20160926173405240)
当我们释放手指时,想让子View滑到一个指定位置,可以用CallBack中的onViewReleased方法:
@Override public void onViewReleased(View releasedChild, float xvel, float yvel) { if (releasedChild == tv) { mViewDrag.settleCapturedViewAt(300,300); invalidate(); } }
当onViewReleased中的invalidate()被调用之后,会不断调用调用computeScroll(),因此,要在ViewDrag类中重写一下这个方法:
@Override public void computeScroll() { if (mDragHelper.continueSettling(true)) { invalidate(); } }
运行效果:
当给tv设置了clickable为ture时,或者子view为Button时,发现根据上述的代码,拖拽子view是没反应的,原因是拖动的时候onInterceptTouchEvent方法,判断是否可以捕获,而在判断的过程中会去判断另外两个回调的方法getViewHorizontalDragRange和getViewVerticalDragRange,只有这两个方法返回大于0的值才能正常的捕获。如果未能正常捕获就会导致手势down后面的move以及up都没有进入到onTouchEvent。
解决方法:
@Override public int getViewHorizontalDragRange(View child) { return getMeasuredWidth() - child.getWidth(); } @Override public int getViewVerticalDragRange(View child) { return getMeasuredHeight() - child.getHeight(); }
参考资料 :
http://blog.csdn.net/u012551350/article/details/51601985
- Android之ViewDragHelper的使用
- android关于ViewDragHelper的使用
- 学习笔记:Android ViewDragHelper的使用
- Android 之 ViewDragHelper 详解
- Android之ViewDragHelper
- android viewdraghelper使用
- Android ViewDragHelper简单使用
- Android ViewDragHelper使用总结
- Android ViewDragHelper 使用详解
- Android开发之使用ViewDragHelper实现侧边栏滑动的效果
- ViewDragHelper的使用
- viewdraghelper的使用
- ViewDragHelper API 的使用
- ViewDragHelper的使用介绍
- ViewDragHelper的使用
- ViewDragHelper的使用
- ViewDragHelper的使用
- ViewDragHelper的使用
- leetcode---Sum Root to Leaf Numbers---树的深度遍历
- 求多个数的最小公倍数
- Java 内存管理机制与内存泄露
- Xcode8去除控制台多余打印(转)
- 2016ICPC北京站网络预选赛F hihoCoder1388 Periodic Signal,FFT|NTT+CRT
- Android之ViewDragHelper的使用
- Error:Authentication scheme ‘all’(Authentication) is not supported by protocol ‘file’
- bzoj 4326: NOIP2015 运输计划 树链剖分+二分+差分数组
- Java内存管理:深入Java内存区域
- Python语言如何入门
- Course Schedule
- ListView中的setOnItemClickListener参数
- UML类图符号 各种关系说明以及举例
- 互联网协议基础知识小结