簡化拖曳的 DropHelper

DropHelper 類別簡化了拖曳功能的實作。DropHelper (隸屬於 Jetpack DragAndDrop 資源庫) 提供回溯至 API 級別 24 的相容性。

使用 DropHelper 來指定放置目標、自訂放置目標醒目顯示,以及定義系統如何處理放置的資料。

設定拖曳來源

如要開始使用,請使用拖曳來源檢視和 OnDragStartListener 建立 DragStartHelper

OnDragStartListener 中覆寫 onDragStart() 方法。為要移動的資料建立 ClipData 物件和 ClipData.Item 物件。在 ClipData 中,提供在 ClipDataClipDescription 物件中儲存的中繼資料。如果不是代表資料移動的拖曳作業,建議您使用 null,而非實際物件。

Kotlin

DragStartHelper(draggableView)
    { view: View, _: DragStartHelper ->
        val item = ClipData.Item(view.tag as? CharSequence)
        val dragData = ClipData(
            view.tag as? CharSequence,
            arrayOf(ClipDescription.MIMETYPE_TEXT_PLAIN),
            item
        )
        view.startDragAndDrop(
            dragData,
            View.DragShadowBuilder(view),
            null,
            0
        )
    }.attach()

Java

new DragStartHelper(draggableView, new DragStartHelper.OnDragStartListener() {
    @Override
    public void onDragStart(View view, DragStartHelper helper) {
        CharSequence tag = (CharSequence) view.getTag();
        ClipData.Item item = new ClipData.Item(tag);
        ClipData dragData = new ClipData(
          tag, new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN}, item);
        view.startDragAndDrop(
          dragData, new View.DragShadowBuilder(view), null, 0);
    }
});

指定放置目標

當使用者在檢視畫面上放開投射陰影時,你必須正確設定檢視畫面,才能接受資料並正確回應。

DropHelper.configureView() 是靜態的超載方法,可讓您指定放置目標。其參數包括以下內容:

舉例來說,如要建立可接受圖片的放置目標,請使用下列任一方法呼叫:

Kotlin

configureView(
    myActivity,
    targetView,
    arrayOf("image/*"),
    options,
    onReceiveContentListener)

// or

configureView(
    myActivity,
    targetView,
    arrayOf("image/*"),
    onReceiveContentListener)

Java

DropHelper.configureView(
    myActivity,
    targetView,
    new String[] {"image/*"},
    options,
    onReceiveContentlistener);

// or

DropHelper.configureView(
    myActivity,
    targetView,
    new String[] {"image/*"},
    onReceiveContentlistener);

第二個呼叫會忽略放置目標設定選項,在此情況下,放置目標醒目顯示顏色會設為主題的次要 (或強調) 顏色,醒目顯示的圓角半徑設為 16 dp,EditText 元件清單則為空白。詳情請參閱下節說明。

設定放置目標

DropHelper.Options 內部類別可讓您設定放置目標。將類別的執行個體提供給 DropHelper.configureView(Activity, View, String[], Options, OnReceiveContentListener 方法。詳情請參閱上一節的說明。

自訂放置目標醒目顯示

DropHelper 會設定放置目標,在使用者將內容拖曳到目標上方時顯示醒目效果。DropHelper 提供預設樣式,DropHelper.Options 則可讓您設定醒目顯示的顏色,以及指定醒目顯示矩形的圓角半徑。

使用 DropHelper.Options.Builder 類別建立 DropHelper.Options 例項並設定設定選項,如以下範例所示:

Kotlin

val options: DropHelper.Options = DropHelper.Options.Builder()
                                      .setHighlightColor(getColor(R.color.purple_300))
                                      .setHighlightCornerRadiusPx(resources.getDimensionPixelSize(R.dimen.drop_target_corner_radius))
                                      .build()

Java

DropHelper.Options options = new DropHelper.Options.Builder()
                                     .setHighlightColor(getColor(R.color.purple_300))
                                     .setHighlightCornerRadiusPx(getResources().getDimensionPixelSize(R.dimen.drop_target_corner_radius))
                                     .build();

處理放置目標中的 EditText 元件

如果目標包含可編輯的文字欄位,DropHelper 也會控制放置目標中的焦點。

放置目標可以是單一資料檢視或檢視區塊階層。如果放置目標檢視區塊階層包含一或多個 EditText 元件,請將元件清單提供給 DropHelper.Options.Builder.addInnerEditTexts(EditText...),以確保放置目標醒目顯示功能和文字資料處理功能都正常運作。

DropHelper 會禁止放置目標檢視區塊階層內的 EditText 元件,在拖曳互動期間從包含的檢視區塊中竊取焦點。

此外,如果拖曳 ClipData 包含文字和 URI 資料,DropHelper 則會選取放置目標的其中一個 EditText 元件來處理文字資料。選取順序是以下列優先順序為準:

  1. 捨棄 ClipDataEditText
  2. 包含文字遊標 (插入點) 的 EditText
  3. 提供給 DropHelper.Options.Builder.addInnerEditTexts(EditText...) 呼叫的第一個 EditText

如要將 EditText 設為預設文字資料處理常式,請將 EditText 做為 DropHelper.Options.Builder.addInnerEditTexts(EditText...) 呼叫的第一個引數傳遞。舉例來說,如果您的放置目標會處理圖片,但包含可編輯的文字欄位 T1T2T3,請將 T2 設為預設值,如下所示:

Kotlin

val options: DropHelper.Options = DropHelper.Options.Builder()
                                      .addInnerEditTexts(T2, T1, T3)
                                      .build()

Java

DropHelper.Options options = new DropHelper.Options.Builder()
                                     .addInnerEditTexts(T2, T1, T3)
                                     .build();

處理放置目標中的資料

DropHelper.configureView() 方法會接受您為了處理拖曳 ClipData 而建立的 OnReceiveContentListener。拖曳資料會提供給 ContentInfoCompat 物件中的事件監聽器。物件中會顯示文字資料。媒體 (例如圖片) 會以 URI 表示。

使用 DropHelper.configureView() 設定下列類型的檢視畫面時,OnReceiveContentListener 也會處理使用者互動 (例如複製和貼上) 以外的使用者互動資料:

  • 所有檢視畫面 (如果使用者執行 Android 12 以上版本)。
  • AppCompatEditText (如果使用者搭載的 Android 版本低於 Android 7.0)。

MIME 類型、權限和內容驗證

DropHelper 的 MIME 類型檢查以拖曳 ClipDescription 為基礎,而這是由提供拖曳資料的應用程式建立。驗證 ClipDescription,確保 MIME 類型設定正確。

DropHelper 會要求拖曳 ClipData 中所含內容 URI 的所有存取權。詳情請參閱DragAndDropPermissions。權限可讓您在處理拖曳資料時解析內容 URI。

DropHelper 不會在解析放置資料中的 URI 時,驗證內容供應器傳回的資料。檢查空值並驗證所有解析的資料正確性。