有多种方式实现全角拖拽,我们基于系统标准的api startDragAndDrop 来做介绍
实现步骤:
一、应用的的拖拽
1.1 通过长按触发
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {@Overridepublic boolean onLongClick(View v) {ClipData dragClipData = ClipData.newPlainText("", "");View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);holder.itemView.startDragAndDrop(dragClipData, shadowBuilder, v, 0);return true;}});
1.2、设置拖拽监听,收到消息后可以处理自己的业务
// 设置放置监听器binding.textView.setOnDragListener((view, dragEvent) -> {float x = dragEvent.getX();float y = dragEvent.getY();switch (dragEvent.getAction()) {case DragEvent.ACTION_DRAG_STARTED:LogUtil.d(TAG, "拖动开始: x=" + x + ", y=" + y);return true;case DragEvent.ACTION_DRAG_LOCATION:LogUtil.d(TAG, "拖动中: x=" + x + ", y=" + y);return true;case DragEvent.ACTION_DROP:LogUtil.d(TAG, "放开拖动: x=" + x + ", y=" + y);return true;case DragEvent.ACTION_DRAG_ENDED:LogUtil.d(TAG, "拖动结束: x=" + x + ", y=" + y);// 拖动结束return true;default:return false;}});
二、应用外的拖拽,可以被第三方应用接受你的拖拽事件
2.1 我们通过分析一张图片给第三方,先把图片放到图库,得到一个uri
public static Uri saveToGallery(Context context, Bitmap bitmap) {ContentValues values = new ContentValues();long currentTimeMillis = System.currentTimeMillis();//这个名称要唯一,否则到了32会报错values.put(MediaStore.Images.Media.DISPLAY_NAME, "image_name" +currentTimeMillis); // 图片名称values.put(MediaStore.Images.Media.DESCRIPTION, "image_description"); // 图片描述values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); // 图片的MIME类型values.put(MediaStore.Images.Media.DATE_TAKEN, currentTimeMillis); // 图片的拍摄日期// 获取外部存储的公共图片目录Uri externalContentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;// 保存图片到系统媒体库try {// 使用ContentResolver将Bitmap保存到指定的UriUri uri = context.getContentResolver().insert(externalContentUri, values);if (uri != null) {OutputStream outputStream = context.getContentResolver().openOutputStream(uri);bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); // 将Bitmap压缩并保存到Uri对应的文件中outputStream.flush();outputStream.close();// 刷新媒体库MediaStore.Images.Media.insertImage(context.getContentResolver(), bitmap, "title", "description");return uri;}} catch (IOException e) {e.printStackTrace();}return null;}
2.2 把图片的uri发送出去,注意 startDragAndDrop的最后一个参数,需要让其他用有权限访问才可以。
val dragClipData = ClipData.newUri(requireContext().contentResolver, "Image", imageUri)
val dragShadow = View.DragShadowBuilder(holder.itemView)
holder.itemView.startDragAndDrop(dragClipData, dragShadow, null,DRAG_FLAG_GLOBAL.or(DRAG_FLAG_GLOBAL_URI_READ).or(DRAG_FLAG_OPAQUE))
如有更多需求,请参考官网示例:
doc地址:Enable drag and drop | Views | Android Developers
源码地址:git@github.com:android/user-interface-samples.git