Android拖拽助手ViewDragHelper的创建与使用实例

目录
  • 前言
  • 创建实例
  • ViewDragHelper.Callback
  • 使用
  • 总结

前言

在项目中,我们经常自定义ViewGroup,有时候需要拖拽它的子View,让其运动,一般情况下如果我们手动处理各种滑动事件,非常麻烦,谷歌给我们提供了一个辅助类ViewDragHelper,ViewDragHelper给我们提供了很多拖拽相关的方法以及状态跟踪。

创建实例

ViewDragHelper.create(vp, callback);

ViewDragHelper的创建比较简单,它的构造函数是私有的,只能通过create()方法创建,第一个参数是一个ViewGroup,也就是需要使用ViewDragHelper的自定义View,第二个参数callback,提供了很多拖拽相关的回调。

ViewDragHelper.Callback

下面是几个常用的方法

private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {
   public boolean tryCaptureView(View child, int pointerId)
   public int getViewHorizontalDragRange(View child)
   public int clampViewPositionHorizontal(View child, int left, int dx)
   public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy)
   public void onViewReleased(View releasedChild, float xvel, float yvel) 
  • tryCaptureView返回一个boolean,用户判断是否捕获当前view的触摸事件
  • getViewHorizontalDragRange获取child水平方向的拖拽范围
  • clampViewPositionHorizontal控制child在水平方向的移动,我们可以通过dx修正left的值,返回值表示我们真正想让child的left变成的值
  • clampViewPositionVertical和水平方向类似
  • onViewPositionChanged 当child位置改变时候的回调
  • onViewReleased当拖拽的view释放的时候回调

使用

自定义一个简单的侧拉菜单,该菜单有两个子View,一个主界面,一个侧边菜单界面

首先自定义一个ViewGroup并初始化ViewDragHelper

public class SlideMenu extends FrameLayout{
    private void init(){
       viewDragHelper = ViewDragHelper.create(this, callback);
    }
}

然后重写onInterceptTouchEvent和onTouchEvent,将这两个方法的处理逻辑交给ViewDragHelper

public boolean onInterceptTouchEvent(MotionEvent ev) {
   return viewDragHelper.shouldInterceptTouchEvent(ev);
}
public boolean onTouchEvent(MotionEvent event) {
   viewDragHelper.processTouchEvent(event);
   return true;
}

实现ViewDragHelper.Callback,重写tryCaptureView,在当前Layout中两个子VIew都需要滑动,所以直接返回true.

public boolean tryCaptureView(View child, int pointerId) {
   return true;
}

先限制一下横向滑动范围,给一个最大值

public int getViewHorizontalDragRange(View child) {
   return (int) dragRange;
}

主界面在滑动过程中,我们需要控制下它在水平方向的移动距离

public int clampViewPositionHorizontal(View child, int left, int dx) {
   if(child==mainView){
      if(left<0)left=0;//限制mainView的左边
      if(left>dragRange)left=(int) dragRange;//限制mainView的右边
   }
   return left;
}

在滑动过程中,根据拖拽回调重新对侧拉菜单和主界面布局,不断刷新他们的位置信息,这里简单起见,让侧拉菜单固定,只是主界面滑动。

public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
   if(changedView==menuView){
      menuView.layout(0, 0, menuView.getMeasuredWidth(),menuView.getMeasuredHeight());
      int newLeft = mainView.getLeft()+dx;
      if(newLeft<0)newLeft=0;
      if(newLeft>dragRange)newLeft=(int) dragRange;mainView.layout(newLeft,mainView.getTop()+dy,newLeft+mainView.getMeasuredWidth(),mainView.getBottom()+dy);
   }
}

当手指抬起释放view的时候,可能我们只是拖拽了一点,这时候我们需要根据当前拖拽的信息决定是打开菜单还是关闭菜单。

public void onViewReleased(View releasedChild, float xvel, float yvel) {
   if(mainView.getLeft()<dragRange/2){
      //在左半边
      close();
   }else {
      //在右半边
      open();
   }
}

对于view的滑动ViewDragHelper也提供了smoothSlideViewTo方法,所以close和open方法就很简单

public void close() {
   viewDragHelper.smoothSlideViewTo(mainView,0,mainView.getTop());
   ViewCompat.postInvalidateOnAnimation(SlideMenu.this);
}
public void computeScroll() {
   if(viewDragHelper.continueSettling(true)){
      ViewCompat.postInvalidateOnAnimation(SlideMenu.this);
   }
}

然后还可以提供一些拖拽状态回调,比如拖拽完成,拖拽中等状态,这些比较简单,直接在onViewPositionChanged中处理就可以了。

最后看一下效果

总结

到此这篇关于Android拖拽助手ViewDragHelper的创建与使用的文章就介绍到这了,更多相关Android拖拽助手ViewDragHelper内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android ViewDragHelper实现京东、淘宝拖拽详情功能的实现

    先上效果图,如果大家感觉不错,请参考实例代码,效果图如下所述: 要实现这个效果有三种方式: ① 手势 ② 动画 ③ ViewDragHelper 这里我使用的是ViewDragHelper类. public class ViewDragLayout extends ViewGroup { //垂直方向的滑动速度 private static final int VEL_THRESHOLD = 300; //垂直方向的滑动距离 private static final int DISTANCE_T

  • Android拖拽助手ViewDragHelper的创建与使用实例

    目录 前言 创建实例 ViewDragHelper.Callback 使用 总结 前言 在项目中,我们经常自定义ViewGroup,有时候需要拖拽它的子View,让其运动,一般情况下如果我们手动处理各种滑动事件,非常麻烦,谷歌给我们提供了一个辅助类ViewDragHelper,ViewDragHelper给我们提供了很多拖拽相关的方法以及状态跟踪. 创建实例 ViewDragHelper.create(vp, callback); ViewDragHelper的创建比较简单,它的构造函数是私有的

  • 微信小程序实现拖拽 image 触摸事件监听的实例

    微信小程序实现拖拽 image 触摸事件监听的实例 需要做个浮在scroll-view之上的button.尝试了一下. 实现效果图: Android中也会有类似移动控件的操作.思路差不多.获取到位移的X Y 的变量,给控件设置坐标. 1.index.wxml <image class="image-style" src="../../images/gundong.png" bindtap="ballClickEvent" style=&qu

  • JS弹出可拖拽可关闭的div层完整实例

    本文实例讲述了JS弹出可拖拽可关闭的div层完整实现方法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xh

  • Vue实现拖拽穿梭框功能四种方式实例详解

    目录 一.使用原生js实现拖拽 二.VUe使用js实现拖拽穿梭框 三.Vue 拖拽组件 vuedraggable 四.Awe-dnd指令封装 一.使用原生js实现拖拽 <html lang="en"> <head> <meta charset="UTF-8" /> <title>Lazyload</title> <style> .drag { background-color: skyblue;

  • android实现拖拽裁剪功能

    本文实例为大家分享了android拖拽框,裁剪出图片的具体代码,供大家参考,具体内容如下 import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.MotionEvent; i

  • react实现拖拽模态框

    前言 实际开发中,模态框展现数据会经常出现.但不幸的是有时功能开发完了,UI同学突然提出需求希望模态框能拖拽.本文使用的模态框由 ant design 3.0 的 Modal 组件封装而成,如何在不修改原来代码的基础上实现拖拽呢.最终效果图如下: 实践 1.创建高阶组件DragHoc 新建文件ModalDrag/index.js,将下面代码copy进去 DragObj是具体拖拽的原生js代码,后面再看 DragHoc是创建高阶组件的函数,其中参数InnerComponent是需要被改造的模态框组

  • Android DragVideo实现播放视频时任意拖拽的方法

    Android DragVideo实现播放视频时任意拖拽 DragVideo A Method to Drag the Video When Playing Video 一种在播放视频时,能够拖拽的方案 为什么有这个工程 经常在爱奇艺网站上看电影,看到如果滑动掩盖了播放窗口后,就后在最下面有一个小播放界面.并且这个播放界面,是可以任意拖拽的.感觉很酷 既然web端能实现,就想了想在移动端设备上,是否也能实现这个效果,于是就有了- 效果图: ------> 实现思路:1.播放视频的view选择Te

  • Android条目拖拽删除功能实例代码

    项目中需求,要做条目条目拖拽删除效果,实际效果和QQ消息删除一样,侧滑有制定和删除. 效果图 第一步效果图 1.0自定义控件 SwipeLayout 继承FrameLayout重写里面三个构造方法,分别调用initView(). 2.0在布局中使用自定义控件 3.0在initView()方法中,创建拖拽辅辅助工具 ViewDragHelper() 该方法需要传入回调 MyCallBack() 4.0,创建MyCallBack()回调,继承ViewDragHelper.Callback 在回调中

  • android ListView和GridView拖拽移位实现代码

    关于ListView拖拽移动位置,想必大家并不陌生,比较不错的软件都用到如此功能了.如:搜狐,网易,百度等,但是相比来说还是百度的用户体验较好,不偏心了,下面看几个示例:             首先说一下:拖拽ListView的item就不应该可以任意移动,只应该在ListView所在的范围内,而网易的你看看我都可以移动到状态栏了,虽然你做了处理,但是用户体验我个人感觉不好,在看看百度的,不仅控制了移动范围,更不错的百度的移动起来会时时的换位,看起来相当的形象,所以我认为这样相当的棒.说明一点

随机推荐