Android TouchListener实现拖拽删实例代码

Android TouchListener实现拖拽删实例代码

如果为一个控件设置了该触摸监听, 控件会随着用户的拖动而移动, 如果拖动的距离大过设置的临界值, 那么当松开手指时会有回调onDragComplete, 用户可在该方法中将该控件从父布局中删除, 或这进行其他操作。 如果用户拖拽的距离小于临界值, 那么当用户松开手指时控件会回谈到原来的初始位置。这时会触发onDragRebound回调。 如果用户触摸控件之后没有拖拽而是直接松开手指, 会触发onClick回调, 这样用户就不用为该控件设置onClick监听。

源码如下:


import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup; 

/**
 * Created by zhangjg on 14-10-10.
 */
public class DragTouchListener implements View.OnTouchListener { 

  /**
   * drag directions
   */
  public static final int DIRECTION_UP = 0;
  public static final int DIRECTION_DOWN = 1;
  public static final int DIRECTION_LEFT = 2;
  public static final int DIRECTION_RIGHT = 3; 

  private int mDragDirection = -1;
  private int mDragDistance = -1;
  private ViewGroup.MarginLayoutParams mParams;
  private ViewGroup.MarginLayoutParams mOriginParams; 

  private int viewOriginMargin = -1000; 

  private float mStartY = 0;
  private float mStartX = 0;
  private boolean isTouched = false; 

  public DragTouchListener(int dragDirection, int dragDistance){
    mDragDirection = dragDirection;
    mDragDistance = dragDistance;
  } 

  protected void onClick(View view){ 

  } 

  protected void onDragComplete(View view){ 

  } 

  protected void onDragRebound(View view){ 

  } 

  @Override
  public boolean onTouch(View view, MotionEvent motionEvent) { 

    if (viewOriginMargin == -1000){
      mParams = (ViewGroup.MarginLayoutParams)view.getLayoutParams();
      if (mDragDirection == DIRECTION_UP) {
        viewOriginMargin = mParams.bottomMargin;
      }else if (mDragDirection == DIRECTION_DOWN){
        viewOriginMargin = mParams.topMargin;
      }else if (mDragDirection == DIRECTION_LEFT){
        viewOriginMargin = mParams.rightMargin;
      }else if (mDragDirection == DIRECTION_RIGHT){
        viewOriginMargin = mParams.leftMargin;
      }
    } 

    int action = motionEvent.getAction();
    switch (action){
      case MotionEvent.ACTION_DOWN:
        isTouched = true;
        mStartY = motionEvent.getY();
        mStartX = motionEvent.getX();
        return true;
      case MotionEvent.ACTION_MOVE:
        float y = motionEvent.getY();
        float x = motionEvent.getX(); 

        if (mDragDirection == DIRECTION_UP){
          if(y < mStartY){
            mParams.bottomMargin = viewOriginMargin +(int) (mStartY - y);
          }
        }else if (mDragDirection == DIRECTION_DOWN){
          if (y > mStartY){
            mParams.topMargin = viewOriginMargin + (int) (y - mStartY);
          }
        }else if (mDragDirection == DIRECTION_LEFT){
          if (x < mStartX){
            mParams.rightMargin = viewOriginMargin + (int) (mStartX - x);
          }
        }else if (mDragDirection == DIRECTION_RIGHT){
          if (x > mStartX){
            mParams.leftMargin = viewOriginMargin + (int) (x - mStartX);
          }
        } 

        view.setLayoutParams(mParams);
        break;
      case MotionEvent.ACTION_UP:
        float nowY = motionEvent.getY();
        float nowX = motionEvent.getX(); 

        int deltaX = (int)nowX - (int)mStartX;
        int deltaY = (int)nowY - (int)mStartY; 

        if (isTouched && Math.abs(deltaX) < 5 && Math.abs(deltaY) < 5){
          onClick(view);
          break;
        } 

        if (mDragDirection == DIRECTION_UP){
          if (isTouched && mStartY - nowY > mDragDistance){ 

//            Log.i("test-drag", "direction up , startY = " + mStartY + ", nowY = " + nowY +
//                ", startY - nowY = " + (mStartY - nowY) + ", dragDistance : " + mDragDistance);
            onDragComplete(view); 

          }else if (mStartY - nowY > 0 && mStartY - nowY < mDragDistance ){
            mParams.bottomMargin = viewOriginMargin;
            view.setLayoutParams(mParams);
            onDragRebound(view);
          }
        }else if (mDragDirection == DIRECTION_DOWN){ 

          if (isTouched && nowY - mStartY > mDragDistance){
            onDragComplete(view);
          }else if ( nowY - mStartY > 0 && nowY - mStartY < mDragDistance ){
            mParams.topMargin = viewOriginMargin;
            view.setLayoutParams(mParams);
            onDragRebound(view);
          }
        }else if (mDragDirection == DIRECTION_LEFT){
          if (isTouched && mStartX - nowX > mDragDistance){
            onDragComplete(view);
          }else if ( mStartX - nowX > 0 && mStartX - nowX < mDragDistance ){
            mParams.rightMargin = viewOriginMargin;
            view.setLayoutParams(mParams);
            onDragRebound(view);
          }
        }else if (mDragDirection == DIRECTION_RIGHT){
          if (isTouched && nowX - mStartX > mDragDistance){
            onDragComplete(view);
          }else if ( nowX - mStartX > 0 && nowX - mStartX < mDragDistance ){
            mParams.leftMargin = viewOriginMargin;
            view.setLayoutParams(mParams);
            onDragRebound(view);
          }
        } 

        isTouched = false; 

        break;
    }
    return false;
  }
}

在使用时继承该类, 并覆盖三个回调方法, 就可以在合适的时机得到回调。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • Android使用MediaRecorder实现录音及播放

    现在项目中有使用到音视频相关技术,在参考了网上各种大牛的资料及根据自己项目实际情况(兼容安卓6.0以上版本动态权限管理等),把声音录制及播放相关代码做个记录. public class MediaRecorderActivity extends BaseActivity { private Button start_tv; private ListView listView; //线程操作 private ExecutorService mExecutorService; //录音API pri

  • Android实现返回键操作思路

    记录用户点击的操作历史,使用栈数据结构,频繁的操作栈顶(添加,获取,删除),使用LinkedList 捕获用户的返回键操作,响应返回键,返回上一个界面 MainActivity.java /** * 返回键处理 */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode==KeyEvent.KEYCODE_BACK){ boolean result=MiddleManager.getInstanc

  • Android几行代码实现监听微信聊天示例

    现在适配微信版本更加容易了,只需要替换一个Recourse-ID即可 可以知道对方发的是小视频还是语音,并获取秒数. 可以区分聊天信息中的图片或者表情 实现效果: 实时监听当前聊天页面的最新一条消息,效果如图: 实现原理: 同样是利用AccessibilityService辅助服务,关于这个服务类还不了解的同学可以先看下我上一篇关于抢红包的博客,原理都一样:http://www.jb51.net/article/104507.htm 1.首先我们先来看一下微信聊天界面的布局,查看方法: Andr

  • Android中activity的启动模式

    activity的启动模式一共有四种:standard.singleTop.singleTask和singleInstance,可以在AndroidMannifest.xml中通过给<activity>标签指定android:launchMode属性来选择启动模式. 1.standard 是活动默认的启动模式,Android是使用返回栈来管理活动,standard模式下,每启动一个新的活动,它就会在返回栈中入栈,并处于栈顶位置.系统不会在乎这个活动是否已经在返回栈中存在,每次启动都会创建该活动

  • Android ScrollView嵌套ExpandableListView显示不正常的问题的解决办法

    Android ScrollView嵌套ExpandableListView显示不正常的问题的解决办法 前言: 关于ScrollView嵌套ExpandableListView导致ExpandableListView显示不正常的问题解决方法有很多,在这里介绍一种小编亲自测试通过的方法. 重写ExpandableListView: 实例代码: package com.jph.view; import android.content.Context; import android.util.Attr

  • Android简易音乐播放器实现代码

    本文实例为大家分享了Android音乐播放器的具体代码,供大家参考,具体内容如下 1.播放项目内的音乐 package com.thm.g150820_android26_playmusic; import Android.media.MediaPlayer; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.wid

  • Android实现屏蔽微信拉黑和删除联系人功能示例

    Android实现屏蔽微信拉黑和删除联系人功能,废话不多说,具体如下: 实现效果: 让微信永远弹不出那个删除的对话框不就相当于屏蔽掉该功能了吗?哈哈效果如图: 实现原理: 1.我们知道,其实微信每次删除联系人都会弹出此页面 2.如果你对AccessibilityService有过了解或者有看过我之前的两篇博客,你会知道,其实每次弹出这个框,都会触发AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED这个事件,所以我们只要在每次触发该事件的时候进行判断当前页面是

  • Android编程之ProgressBar圆形进度条颜色设置方法

    本文实例讲述了Android ProgressBar圆形进度条颜色设置方法.分享给大家供大家参考,具体如下: 你是不是还在为设置进度条的颜色而烦恼呢--别着急,且看如下如何解决. ProgressBar分圆形进度条和水平进度条 我这里就分享下如何设置圆形进度条的颜色吧,希望对大家会有帮助. 源码如下: 布局文件代码: <ProgressBar android:id="@+id/progressbar" android:layout_width="wrap_content

  • Android TouchListener实现拖拽删实例代码

    Android TouchListener实现拖拽删实例代码 如果为一个控件设置了该触摸监听, 控件会随着用户的拖动而移动, 如果拖动的距离大过设置的临界值, 那么当松开手指时会有回调onDragComplete, 用户可在该方法中将该控件从父布局中删除, 或这进行其他操作. 如果用户拖拽的距离小于临界值, 那么当用户松开手指时控件会回谈到原来的初始位置.这时会触发onDragRebound回调. 如果用户触摸控件之后没有拖拽而是直接松开手指, 会触发onClick回调, 这样用户就不用为该控件

  • Android仿美团拖拽效果实例代码

    效果图 如上图,实现了拖拽事件的无缝过渡.效果很流畅很自然,之所以写轮子因为实在找不到好用的库,该库参考了https://github.com/woxingxiao/SlidingUpPanelLayout ,其实在大神的开源库里就有Issues提到内嵌 scrollView 时滑动冲突的问题.再加上最近项目里面的详情页就有这样的拖拽效果需求,只好自己实现一遍. 在实现的过程中,就遇到几个比较棘手的问题,也经过了一番挣扎才想出解决的方案. 困难 拖拽释放的时机,如下拉1/6就自动收缩否则回弹,上

  • js实现弹出框的拖拽效果实例代码详解

    具体代码如下所示: //HTML部分 <div class="wrap"></div> <div class="popUpBox"> <div class="layer-head"><div class="layer-head-text">弹出框</div><div class="layer-close"></div&

  • JS实现简易的图片拖拽排序实例代码

    由HTML5的拖放API,实现的简易图片拖放效果. 一.HTML5拖放API的知识点 首先我们得知道元素怎么才可以被拖放,需要设置它们的draggable属性,其中img和a标签的dragable属性默认是true,不需要我们手动设置. 拖放API的监听事件如下: dragstart: 源对象拖拽开始: drag: 源对象拖拽的过程中: dragend: 源对象拖拽结束: dragenter: 进入过程对象区域; dragover: 在过程对象区域内移动: dragleave: 离开过程对象区域

  • js 表格拖拽效果实例代码 (IE only)

    Table Test (I.E. Only) /*得到表格列*/ function getCols(srcCellIndex,obj) { obj = typeof obj === 'string' ? document.getElementById(obj) : obj; var s = ''; s += ' ' s += obj.rows[0].cells[srcCellIndex].innerHTML + ' '; for(var i = 1;i ' + obj.rows[i].cells

  • Android中RecyclerView拖拽、侧删功能的实现代码

    废话不多说,下面展示一下效果. 这是GridView主文件实现. public class GridViewActivity extends AppCompatActivity { RecyclerView mRecyclerView; List<String> mStringList; RecyclerAdapter mRecyAdapter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { s

  • Android实现可拖拽列表和多选功能

    本文实例为大家分享了Android实现可拖拽列表和多选的具体代码,供大家参考,具体内容如下 这是我已经完成的一个已经上线的OA软件的一个模块,这个模块的功能不多,已经放到GitHub上面开源了,有感兴趣的朋友可以看看UIFrame 主窗口JAVA代码 /** * 编辑状态下长按拖动条目 * 1.通过ItemTouchHelper.Callback实现长按拖动 * 2.通过isEditable的值判断是否编辑状态,初值是false * 3.切换编辑状态要把isEditable的值取反,并改变复选框

  • android自定义可拖拽的仪表盘

    本文实例为大家分享了android自定义可拖拽的仪表盘的具体代码,供大家参考,具体内容如下 因为项目最近需要用到仪表盘,又不想使用之前使用的背景图的方式.主要是想自己写一点代码.觉得绘制要比图片好.于是有了下面这张图: 面从弧度,刻度,文字,指针都是canvas绘制出来的. /** * Created by xulc on 2018/7/18. */ public class DashboardView extends View { private int minWidthDP = 200; p

  • Android实现View拖拽跟随手指移动效果

    今天想实现这个功能,但是网上搜索代码,都是利用setPadding,setMargin 等方法去实现的,这在Android 4.0 以前是没问题的,但是,android 4.0 后系统已经提供了更简单的方法给我们用了,就是setTranslationX() 和setTranslationY() .这两个是View的属性方法.现在我就用这两个方法实现一个View可以跟着手指移动拖拽的效果.代码非常非常简单: public class DragView extends TextView { floa

  • Android自定义可拖拽的悬浮按钮DragFloatingActionButton

    悬浮按钮FloatingActionButton是Android 5.0系统添加的新控件,FloatingActionButton是继承至ImageView,所以FloatingActionButton拥有ImageView的所有属性.本文讲解的是一个实现了可拖拽的悬浮按钮,并为此添加了类似于qq的吸附边框的功能.在此之前,先了解下其简单的使用方式吧: 首先你得添加其依赖 compile 'com.android.support:design:25.3.1' 然后在布局文件中使用. <andro

随机推荐