Skip to content

Commit ee7d25e

Browse files
feat/add-drag-drop : Add Drag & Drop Functionality
1 parent bf544b7 commit ee7d25e

3 files changed

Lines changed: 76 additions & 1 deletion

File tree

app/src/main/java/com/example/cahier/MainActivity.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import androidx.core.content.IntentCompat
3030
import com.example.cahier.core.data.NoteType
3131
import com.example.cahier.features.home.CahierApp
3232
import com.example.cahier.core.ui.theme.CahierAppTheme
33+
import com.example.cahier.core.utils.createDragAndDropTarget
3334
import dagger.hilt.android.AndroidEntryPoint
3435

3536
@AndroidEntryPoint
@@ -48,7 +49,9 @@ class MainActivity : ComponentActivity() {
4849
setContent {
4950
CahierAppTheme {
5051
Surface(
51-
modifier = Modifier.fillMaxSize(),
52+
modifier = Modifier
53+
.fillMaxSize()
54+
.createDragAndDropTarget(this),
5255
color = MaterialTheme.colorScheme.background
5356
) {
5457
CahierApp(noteId = noteId, noteType = noteType)

app/src/main/java/com/example/cahier/core/utils/DragAndDropUtils.kt

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,27 @@
1818

1919
package com.example.cahier.core.utils
2020

21+
import android.app.Activity
22+
import android.app.PendingIntent
23+
import android.content.ClipData
24+
import android.content.ClipDescription
25+
import android.content.Intent
2126
import android.net.Uri
27+
import android.os.Build
2228
import android.view.DragAndDropPermissions
29+
import android.view.View
2330
import androidx.activity.ComponentActivity
31+
import androidx.annotation.RequiresApi
2432
import androidx.compose.foundation.ExperimentalFoundationApi
33+
import androidx.compose.foundation.draganddrop.dragAndDropSource
34+
import androidx.compose.foundation.draganddrop.dragAndDropTarget
35+
import androidx.compose.ui.Modifier
2536
import androidx.compose.ui.draganddrop.DragAndDropEvent
2637
import androidx.compose.ui.draganddrop.DragAndDropTarget
38+
import androidx.compose.ui.draganddrop.DragAndDropTransferData
2739
import androidx.compose.ui.draganddrop.toAndroidDragEvent
40+
import com.example.cahier.AppArgs
41+
import com.example.cahier.core.data.Note
2842

2943
@OptIn(ExperimentalFoundationApi::class)
3044
fun createDropTarget(
@@ -43,3 +57,58 @@ fun createDropTarget(
4357
}
4458
}
4559
}
60+
61+
fun Modifier.createDragAndDropSource(
62+
activity: Activity?,
63+
note: Note
64+
): Modifier = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
65+
dragAndDropSource { _ ->
66+
activity?.let {
67+
DragAndDropTransferData(
68+
clipData = getClipData(it, note),
69+
flags = View.DRAG_FLAG_GLOBAL_SAME_APPLICATION or View.DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG,
70+
)
71+
}
72+
}
73+
} else {
74+
this
75+
}
76+
77+
fun Modifier.createDragAndDropTarget(
78+
activity: Activity
79+
): Modifier = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
80+
dragAndDropTarget(
81+
shouldStartDragAndDrop = { event ->
82+
event.toAndroidDragEvent().clipDescription?.hasMimeType(ClipDescription.MIMETYPE_TEXT_INTENT) ?: false
83+
},
84+
target = object : DragAndDropTarget {
85+
override fun onDrop(event: DragAndDropEvent): Boolean =
86+
event.toAndroidDragEvent().clipData?.getItemAt(0)?.intent?.let {
87+
activity.startActivity(it)
88+
true
89+
} ?: false
90+
}
91+
)
92+
} else {
93+
this
94+
}
95+
96+
97+
@RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM)
98+
fun getClipData(activity: Activity, note: Note): ClipData {
99+
val componentName = activity.componentName
100+
val intent = Intent.makeMainActivity(componentName).apply {
101+
putExtra(AppArgs.NOTE_ID_KEY, note.id)
102+
putExtra(AppArgs.NOTE_TYPE_KEY, note.type)
103+
flags = Intent.FLAG_ACTIVITY_NEW_TASK or
104+
Intent.FLAG_ACTIVITY_MULTIPLE_TASK or
105+
Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT
106+
}
107+
val pendingIntent = PendingIntent.getActivity(
108+
activity, 0, intent, PendingIntent.FLAG_IMMUTABLE
109+
)
110+
return ClipData(
111+
AppArgs.NOTE_ID_KEY, arrayOf(ClipDescription.MIMETYPE_TEXT_INTENT),
112+
ClipData.Item.Builder().setIntentSender(pendingIntent.intentSender).build()
113+
)
114+
}

app/src/main/java/com/example/cahier/features/home/HomeScreenComponents.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
package com.example.cahier.features.home
2020

21+
import androidx.activity.compose.LocalActivity
2122
import androidx.compose.animation.AnimatedVisibility
2223
import androidx.compose.animation.fadeIn
2324
import androidx.compose.animation.fadeOut
@@ -75,6 +76,7 @@ import com.example.cahier.R
7576
import com.example.cahier.core.data.Note
7677
import com.example.cahier.core.data.NoteType
7778
import com.example.cahier.core.ui.theme.CahierAppTheme
79+
import com.example.cahier.core.utils.createDragAndDropSource
7880
import com.example.cahier.features.drawing.DrawingDetailThumbnail
7981

8082
@Composable
@@ -212,6 +214,7 @@ fun NoteItem(
212214
.fillMaxWidth()
213215
.clip(CardDefaults.outlinedShape)
214216
.clickable { onClick() }
217+
.createDragAndDropSource(LocalActivity.current, note)
215218
) {
216219
NoteItemContent(note)
217220
NoteItemActions(onToggleFavorite, note, onDelete, onNewWindow, isCompact)

0 commit comments

Comments
 (0)