话不多说直接上代码:

首先是XML文件代码:

<LinearLayout                     android:layout_width="match_parent"                     android:layout_height="match_parent" android:orientation="horizontal"      >                <LinearLayout                    android:id="@+id/release_img0_layout"                    android:layout_width="0px"                    android:layout_height="match_parent"                    android:layout_marginLeft="20px"                    android:layout_weight="1">                     <ImageView                        android:id="@+id/release_img0"                        android:layout_width="match_parent"                        android:layout_height="match_parent"                        android:scaleType="centerCrop" />                 </LinearLayout>                 <LinearLayout                    android:id="@+id/release_img1_layout"                    android:layout_width="0px"                    android:layout_height="match_parent"                    android:layout_marginLeft="20px"                    android:layout_weight="1">                     <ImageView                        android:id="@+id/release_img1"                        android:layout_width="match_parent"                        android:layout_height="match_parent"                        android:scaleType="centerCrop" />                 </LinearLayout> </LinearLayout>

重点注意,两个ImageView要分别用Layout单独装起来,后面会说原因

接下来是初始化:

 mImg0 = findViewById(R.id.release_img0); mImg1 = findViewById(R.id.release_img1);mImg0_layout = findViewById(R.id.release_img0_layout);mImg1_layout = findViewById(R.id.release_img1_layout);//添加ImageView的触摸监听和各自父布局的拖拽监听 mImg0.setOnTouchListener(ImgUtils.MyTouchEvent); mImg0_layout.setOnDragListener(ImgUtils.MyDragListener); mImg1.setOnTouchListener(ImgUtils.MyTouchEvent); mImg1_layout.setOnDragListener(ImgUtils.MyDragListener);

监听详情:

public class ImgUtils {    private static long lastTime;    public static View.OnTouchListener MyTouchEvent = new View.OnTouchListener() {        @Override        public boolean onTouch(View v, MotionEvent event) {            if (event.getAction() == MotionEvent.ACTION_DOWN) {                LogUtils.loge("ACTION_DOWN");                long lastTime1 = System.currentTimeMillis();                 lastTime=lastTime1;                ClipData data = ClipData.newPlainText("", "");                View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);                v.startDrag(data, shadowBuilder, v, 0);                if ((lastTime1-lastTime)<200){                    v.setAlpha((float) 1.0);                    return false;                }                v.setAlpha((float) 0.5);            } else if (event.getAction() == MotionEvent.ACTION_UP){                LogUtils.loge("ACTION_UP");                long time = System.currentTimeMillis();                if ((time - lastTime)<500){ // 间隔小于500毫秒,视为点击事件                    return false;                }            }else if (event.getAction() == MotionEvent.ACTION_MOVE){                LogUtils.loge("ACTION_MOVE");            }             return false;         }    };     public static View.OnDragListener MyDragListener = new View.OnDragListener() {         @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)        @Override        public boolean onDrag(View v, DragEvent event) {            View visitorView = (View) event.getLocalState();            if (visitorView == null) return true;            ViewGroup visitorOwner = (ViewGroup) visitorView.getParent();            ViewGroup visitedOwner = (ViewGroup) v;            View visitedImage = visitedOwner.getChildAt(0);            switch (event.getAction()) {                case DragEvent.ACTION_DRAG_ENTERED:                    v.setAlpha((float)0.7);                    break;                case DragEvent.ACTION_DROP:                    visitedImage.setAlpha((float)1.0);                    if (visitorOwner != visitedOwner) {                        visitedOwner.removeView(visitedImage);                        visitorOwner.removeView(visitorView);                        visitorOwner.addView(visitedImage);                        LinearLayout container = (LinearLayout) v;                        container.addView(visitorView);                    }else {                        visitedImage.performClick(); // 如果归复原位  响应点击事件                    }                    break;                case DragEvent.ACTION_DRAG_ENDED:                    v.setAlpha((float)1.0);                    visitedImage.setAlpha((float)1.0);                    break;                case DragEvent.ACTION_DRAG_EXITED:                    v.setAlpha((float)1.0);                    break;            }            return true;        }    };  }

在这里,我将监听提出来写成了公共的静态方法,

一方面是为了复用,

另一方面是为了多个ImageView互相拖拽时候的多指拖动冲突.核心思想:判断子控件触摸监听的调用间隔.

另外,我这边处理了点击事件和滑动事件的冲突,核心思想:在父布局的拖拽监听里判断子控件拖出去是否放回了原处,如放回了原处,则调用子控件的模拟点击,

点击与滑动冲突的原因:
1.当滑动监听返回true的时候,消费了点击事件,导致点击事件无法触发(源码角度)

2.当OnTouchListener 中的按下事件开始执行拖动时,OnTouchListener 无法收到UP事件(受拖拽影响),

3.即使OnTouchListener 监听中写了返回false,仍然会因为开启了拖拽而被提前返true.

点击与滑动冲突的解决思想:
1.在父布局的拖拽监听中, 判断他的起点和终点是否在同一个layout中

2.如满足第一点条件,则获取layout的第一个孩子,执行孩子的点击事件(模拟点击performClick());

更多相关文章

  1. Android 浅析View的事件分发机制
  2. Android中父View和子view的点击事件
  3. Android报表控件achartengine介绍(二)
  4. 学习笔记_android四种点击事件方法
  5. Android-Charts,Android图形图表控件
  6. GifView控件,android显示gif图片
  7. Android适配器及其控件
  8. Android NestedScrolling解决滑动冲突问题(1) - 相关接口

随机推荐

  1. android消息机制
  2. 制作登录界面的布局时候,可以使用 android
  3. Android布局属性大全
  4. android 安卓 开发 图片库获得图片的绝对
  5. android 设置全屏的三种方式
  6. [置顶] Linux下安装配置Android开发环境
  7. qt for android
  8. Android简单实现音乐播放器
  9. 笔记!
  10. Android(安卓)左右滑屏效果