版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhaihaohao1/article/details/85608380
Android中的拖拽功能是有自带的api的;(很多时候会误以为要自定义控件,所以我放到了,自定义目录下)
参考文档:
http://www.android-doc.com/guide/topics/ui/drag-drop.html
我写了一个例子分析:
效果图:
思路:
1主要用到了View的startDrag(startDragAndDrop API24+) 方法
2拖拽的监听OnDragListener方法
该讲的在上一篇已经讲过了,这里直接贴代码了:
上一篇路径:https://blog.csdn.net/zhaihaohao1/article/details/85605326
SecondActivity中
package com.zhh.android;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.util.TypedValue;
import android.view.DragEvent;
import android.view.HapticFeedbackConstants;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
/**
* 布局文件中子控件,拖拽交换位置
*/
public class SecondActivity extends Activity {
private ImageView imageView0;
private ImageView imageView1;
private ImageView imageView2;
private ImageView imageView3;
private LinearLayout ll_blue;
private Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = SecondActivity.this;
setContentView(R.layout.activity_second);
imageView0 = (ImageView) findViewById(R.id.imageView0);
imageView1 = (ImageView) findViewById(R.id.imageView1);
imageView2 = (ImageView) findViewById(R.id.imageView2);
imageView3 = (ImageView) findViewById(R.id.imageView3);
ll_blue = (LinearLayout) findViewById(R.id.ll_blue);
imageView0.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
v.startDrag(null, shadowBuilder, imageView0, 0);
//震动反馈
v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
return true;
}
});
imageView1.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
v.startDrag(null, shadowBuilder, imageView1, 1);
//震动反馈
v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
return true;
}
});
imageView2.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
v.startDrag(null, shadowBuilder, imageView2, 2);
//震动反馈
v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
return true;
}
});
imageView3.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
v.startDrag(null, shadowBuilder, imageView3, 3);
//震动反馈
v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
return true;
}
});
ll_blue.setOnDragListener(new View.OnDragListener() {
@Override
public boolean onDrag(View v, DragEvent event) {
//v 永远是设置该监听的view,这里即fl_blue
String simpleName = v.getClass().getSimpleName();
Log.w("111", "view name:" + simpleName);
//获取事件
int action = event.getAction();
switch (action) {
case DragEvent.ACTION_DRAG_STARTED:
Log.i("111", "开始拖拽");
break;
case DragEvent.ACTION_DRAG_ENTERED:
Log.i("111", "拖拽的view进入监听的view时");
break;
case DragEvent.ACTION_DRAG_EXITED:
Log.i("111", "拖拽的view离开监听的view时");
break;
case DragEvent.ACTION_DRAG_LOCATION:
float x = event.getX();
float y = event.getY();
long l = SystemClock.currentThreadTimeMillis();
Log.i("111", "拖拽的view在监听view中的位置:x =" + x + ",y=" + y);
break;
case DragEvent.ACTION_DROP:
Log.i("111", "释放拖拽的view");
// 这里拿到的是 startDrag 里面第三个参数
ImageView imageView = (ImageView) event.getLocalState();
// 判断拖拽的是第一张图
if (imageView.getId() == R.id.imageView0) {
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 200);
// layoutParams.topMargin = (int) event.getY() - imageView1.getWidth() / 2;
// layoutParams.leftMargin = (int) event.getX() - imageView1.getHeight() / 2;
((ViewGroup) imageView.getParent()).removeView(imageView);
// ll_blue.addView(imageView1, layoutParams);
int getY = px2dip(context, event.getY());
// 每个子控件的高度都是200,两个就是400,三个就是600,四个就是800
if (getY < 200) {
ll_blue.addView(imageView, 0);
}
if (getY > 200 && getY < 400) {
ll_blue.addView(imageView, 1);
}
if (getY > 400 && getY < 600) {
ll_blue.addView(imageView, 2);
}
if (getY > 600 && getY < 800) {
ll_blue.addView(imageView, 3);
}
}
// 判断拖拽的是第二张图
if (imageView.getId() == R.id.imageView1) {
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 200);
// layoutParams.topMargin = (int) event.getY() - imageView1.getWidth() / 2;
// layoutParams.leftMargin = (int) event.getX() - imageView1.getHeight() / 2;
((ViewGroup) imageView.getParent()).removeView(imageView);
// ll_blue.addView(imageView1, layoutParams);
int getY = px2dip(context, event.getY());
if (getY < 200) {
ll_blue.addView(imageView, 0);
}
if (getY > 200 && getY < 400) {
ll_blue.addView(imageView, 1);
}
if (getY > 400 && getY < 600) {
ll_blue.addView(imageView, 2);
}
if (getY > 600 && getY < 800) {
ll_blue.addView(imageView, 3);
}
}
// 判断拖拽的是第三张图
if (imageView.getId() == R.id.imageView2) {
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 200);
// layoutParams.topMargin = (int) event.getY() - imageView1.getWidth() / 2;
// layoutParams.leftMargin = (int) event.getX() - imageView1.getHeight() / 2;
((ViewGroup) imageView.getParent()).removeView(imageView);
// ll_blue.addView(imageView1, layoutParams);
int getY = px2dip(context, event.getY());
if (getY < 200) {
ll_blue.addView(imageView, 0);
}
if (getY > 200 && getY < 400) {
ll_blue.addView(imageView, 1);
}
if (getY > 400 && getY < 600) {
ll_blue.addView(imageView, 2);
}
if (getY > 600 && getY < 800) {
ll_blue.addView(imageView, 3);
}
}
// 判断拖拽的是第四张图
if (imageView.getId() == R.id.imageView3) {
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 200);
// layoutParams.topMargin = (int) event.getY() - imageView1.getWidth() / 2;
// layoutParams.leftMargin = (int) event.getX() - imageView1.getHeight() / 2;
((ViewGroup) imageView.getParent()).removeView(imageView);
// ll_blue.addView(imageView1, layoutParams);
int getY = px2dip(context, event.getY());
if (getY < 200) {
ll_blue.addView(imageView, 0);
}
if (getY > 200 && getY < 400) {
ll_blue.addView(imageView, 1);
}
if (getY > 400 && getY < 600) {
ll_blue.addView(imageView, 2);
}
if (getY > 600 && getY < 800) {
ll_blue.addView(imageView, 3);
}
}
break;
case DragEvent.ACTION_DRAG_ENDED:
Log.i("111", "结束拖拽");
break;
}
//是否响应拖拽事件,true响应,返回false只能接受到ACTION_DRAG_STARTED事件,后续事件不会收到
return true;
}
});
}
/**
* dp转为px
* Android内部是px
*
* @param context 上下文
* @param dipValue dp值
* @return
*/
public static int dip2px(Context context, float dipValue) {
Resources r = context.getResources();
return (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, dipValue, r.getDisplayMetrics());
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
*/
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
}
布局文件:activity_second.xml中
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/ll_blue"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#4043f1"
android:orientation="vertical"
>
<ImageView
android:id="@+id/imageView0"
android:layout_width="match_parent"
android:layout_height="200dp"
android:src="@mipmap/mn1"
android:scaleType="fitXY"
/>
<ImageView
android:id="@+id/imageView1"
android:layout_width="match_parent"
android:layout_height="200dp"
android:src="@mipmap/mn2"
android:scaleType="fitXY"
/>
<ImageView
android:id="@+id/imageView2"
android:layout_width="match_parent"
android:layout_height="200dp"
android:src="@mipmap/mn3"
android:scaleType="fitXY"
/>
<ImageView
android:id="@+id/imageView3"
android:layout_width="match_parent"
android:layout_height="200dp"
android:src="@mipmap/mn4"
android:scaleType="fitXY"
/>
</LinearLayout>
</ScrollView>
</LinearLayout>
缓存拖拽后的位置(就是下次再打开的时候是你拖拽的位置)在源码中有:
源码下载:
https://download.csdn.net/download/zhaihaohao1/10890390