仿es文件浏览器的拖拽功能
github的地址:https://github.com/originzyf/DragFileMessage
gif图录得不好 第一次搞
这段代码是recycleview内部拖拽的主要方法
@Override
public boolean onDrag(View v, DragEvent event) {
if (!(event.getLocalState() instanceof DragState)) {
return false;
}
final DragState dragState = (DragState) event.getLocalState();
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
dragListener.notifyItemChange(dragListener.getPosition(dragState.getItem()), dragState.getItemId());
break;
case DragEvent.ACTION_DRAG_ENTERED:
break;
case DragEvent.ACTION_DRAG_LOCATION:
if (fromPosition == -1) {
//获取源文件的position
fromPosition = dragListener.getPosition(dragState.getItem());
}
//更新item背景
dragListener.setItemColor(fromPosition, getToPosition(event));
break;
case DragEvent.ACTION_DRAG_EXITED:
dragListener.setAllColor();
break;
case DragEvent.ACTION_DRAG_ENDED:
//重置一些参数
dragListener.notifyItemChange(dragListener.getPosition(dragState.getItem()), DragListener.NO_ID);
fromPosition = -1;
nextMoveTouchPoint.set(MIN_VALUE, MIN_VALUE);
break;
case DragEvent.ACTION_DROP:
//删除源文件的item 并移动文件
dragListener.onDragEnd(fromPosition, getToPosition(event));
textListener.setTextVisibility(View.GONE, R.color.white);
break;
}
return true;
}
这段代码是拖拽目标超出recycleview范围的时候的监听
container.setOnDragListener(new View.OnDragListener() {
@Override
public boolean onDrag(View view, DragEvent dragEvent) {
//获取view 的坐标
int maxWidth = remove.getWidth();
int maxHight = remove.getHeight();
dragX = dragEvent.getX();
dragY = dragEvent.getY();
//选中了删除 改名等功能
if ((dragX - x) < maxWidth && (dragY - y) > 0 && (dragY - y) < maxHight && dragX > 0) {
removeCount = 0;
remove.setBackgroundResource(R.color.blue);
} else {
remove.setBackgroundResource(R.color.gray);
removeCount = -1;
}
if ((width - dragX) < maxWidth && (width - dragX) > 0 && dragY < 120) {
renameCount = 0;
rename.setBackgroundResource(R.color.blue);
} else {
rename.setBackgroundResource(R.color.gray);
renameCount = -1;
}
if (dragY > 1000) {
View child1 = rv.findChildViewUnder(dragX, hight - dragY);
if (child1 != null) {
int toPosition = rv.getChildViewHolder(child1).getAdapterPosition();
if (lastPosition == -1)
lastPosition = toPosition;
else {
if (lastPosition != toPosition) {
setChildBackground(lastPosition, Color.WHITE, true);
lastPosition = toPosition;
}
}
setChildBackground(toPosition, Color.BLUE, false);
copyCount = 0;
}
} else {
copyCount = -1;
if (lastPosition != -1)
setChildBackground(lastPosition, Color.WHITE, true);
}
if (dragEvent.getAction() == DragEvent.ACTION_DROP) {
if (onLongPosition == -1)
return true;
String absolutePath = contentAdapter.getData().get(onLongPosition).getFile().getAbsolutePath();
if (removeCount == 0)
showDeleteDialog(mActivity, absolutePath, onLongPosition, contentAdapter);
else if (renameCount == 0)
showRenameDialog(mActivity, absolutePath, contentAdapter, contentList);
else if (copyCount == 0) {
if (lastPosition == -1)
return true;
AlertDialog.Builder inputDialog = new AlertDialog.Builder(mActivity);
inputDialog.setTitle("是否复制").setPositiveButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
File file1 = arrayList.get(lastPosition).getFile();
entity entity = contentList.get(onLongPosition);
File file2 = new File(file1.getAbsolutePath() + "/" + entity.getFile().getName());
if (!file2.exists())
file2.mkdirs();
if (FileUtils.moveDirectory(entity.getFile().getAbsolutePath(), file2.getAbsolutePath())) {
mPresenter.getPathDate(contentList, SDCarePath + path + "/", false);
contentAdapter.notifyDataSetChanged();
showToast("移动成功");
} else
showToast("移动失败");
lastPosition = -1;
}
}).show();
}
setTextVisibility(View.GONE, R.color.white);
}
return true;
}
});
实现思路是给最外层的布局添加监听 然后根据手指的选中坐标换算相对于最外层布局的xy坐标
根据xy轴获取recycleview 的item的holder
View child = rv.getLayoutManager().findViewByPosition(pos);
mData.get(pos).b = isColor;
if (null != child) {
BaseViewHolder holder = (BaseViewHolder) rv.getChildViewHolder(child);
holder.setBackgroundColor(R.id.line, color);
notifyItemChanged(pos);
}