Untitled
unknown
plain_text
5 months ago
21 kB
2
Indexable
package com.htd.myapplication.ui.main.components import android.annotation.SuppressLint import android.content.Context import android.util.DisplayMetrics import android.util.Log import android.view.ViewGroup import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.pager.PagerState import androidx.compose.material.Text import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.layout.positionInWindow import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.compose.ui.viewinterop.AndroidView import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import com.google.accompanist.drawablepainter.rememberDrawablePainter import com.htd.myapplication.MainActivity import com.htd.myapplication.R import com.htd.myapplication.data.AppPackage import com.htd.myapplication.ui.main.MainViewModel import com.htd.myapplication.ui.theme.dp1 import kotlinx.coroutines.launch import org.burnoutcrew.reorderable.ReorderableItem import org.burnoutcrew.reorderable.detectReorderAfterLongPress import org.burnoutcrew.reorderable.rememberReorderableLazyGridState import org.burnoutcrew.reorderable.reorderable import kotlin.math.min @Composable fun ListApp( numberPages: Int, viewModel: MainViewModel, appStateList: MutableList<AppPackage>, modifier: Modifier ) { val context = LocalContext.current val openDeleteApp by viewModel.openDeleteApp.collectAsState() var size1 by remember { mutableStateOf(IntSize.Zero) } val positionDel = remember { mutableStateOf(0) } val isNavigateApp by viewModel.isNavigateMode.collectAsState() if (appStateList.isEmpty()) { val temp = viewModel.listApps.collectAsState(); appStateList.addAll(temp.value) } var appAdapter = remember { AppAdapter().apply { this.appList = appStateList.toList() this.viewModel = viewModel } } LaunchedEffect(key1 = appStateList) { appAdapter.appList = appStateList.toList() appAdapter.notifyDataSetChanged() } Box( modifier = modifier .fillMaxSize() .onSizeChanged { size1 = it } ) { var isInUninstallZone by remember { mutableStateOf(false) } Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally ) { AndroidView( modifier = Modifier .fillMaxHeight(0.9f) .padding(vertical = 10.dp) .fillMaxWidth(), factory = { context -> RecyclerView(context).apply { layoutManager = GridLayoutManager(context, 5) adapter = appAdapter layoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ) // Setup ItemTouchHelper for drag and drop val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT, 0) { override fun onMove( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder ): Boolean { // Regular drag and drop val fromPosition = viewHolder.adapterPosition val toPosition = target.adapterPosition appStateList.add(toPosition, appStateList.removeAt(fromPosition)) adapter?.notifyItemMoved(fromPosition, toPosition) return true } override fun onSelectedChanged( viewHolder: RecyclerView.ViewHolder?, actionState: Int ) { super.onSelectedChanged(viewHolder, actionState) if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) { viewHolder?.itemView?.alpha = 0.5f viewModel._openDeleteApp.value = true } } override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { // No swipe action } override fun onChildDraw( c: android.graphics.Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean ) { // Check if the view is in the uninstall zone val itemView = viewHolder.itemView val recyclerViewHeight = recyclerView.height val itemBottom = itemView.bottom // Get the screen width and the x position of the dragged item val screenWidth = recyclerView.width val itemLeft = itemView.left val itemRight = itemView.right // Define uninstall zone: bottom 100px and width centered val uninstallZoneWidth = 200 / DisplayMetrics().density val uninstallZoneLeft = (screenWidth - uninstallZoneWidth) / 2 val uninstallZoneRight = uninstallZoneLeft + uninstallZoneWidth Log.e("anth", "onChildDraw: ${itemBottom} ${recyclerViewHeight} ${itemLeft} ${uninstallZoneLeft} ") // Check if item is within the bottom and centered uninstall zone val isDraggingIntoUninstallZone = itemBottom > recyclerViewHeight - 300 && // Bottom 100px itemLeft >= uninstallZoneLeft isInUninstallZone = isDraggingIntoUninstallZone super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) } override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) { super.clearView(recyclerView, viewHolder) if (isInUninstallZone) { isInUninstallZone = false val position = viewHolder.adapterPosition if (position != RecyclerView.NO_POSITION) { val appInfo = appStateList[position] MainActivity.getInstance()?.uninstallApp(appInfo.pkgId) positionDel.value = position } } viewModel._openDeleteApp.value = false viewHolder.itemView.alpha = 1f Log.e("anth", "clearView: check " + isInUninstallZone) } override fun isLongPressDragEnabled(): Boolean { return true } }) itemTouchHelper.attachToRecyclerView(this) } }, update = { if (appAdapter.itemCount != appStateList.size) { appStateList.removeAt(positionDel.value) appAdapter.appList = appStateList.toList() Log.e("anth", "ListApp: need update adapter") } } ) // Uninstall Zone (Bottom of the Screen with specific width) if (openDeleteApp) { Box( modifier = Modifier .fillMaxWidth() .height(100.dp), contentAlignment = Alignment.Center ) { Box( modifier = Modifier .width(200.dp) // Set a specific width for the drop zone .fillMaxHeight() .background(Color.Transparent), // Transparent background for inner box contentAlignment = Alignment.Center ) { Image( painter = painterResource(id = R.drawable.image_uninstall_app), contentDescription = "", modifier = Modifier.size(width= 100.dp1, height = 30.dp1) ) } } } } } } @SuppressLint("CoroutineCreationDuringComposition", "StateFlowValueCalledInComposition") @OptIn(ExperimentalFoundationApi::class) @Composable private fun HorizontalGrid( list: List<AppPackage>, context: Context, viewModel: MainViewModel, pagerState: Any, listApps: List<AppPackage>, width: Int, height: Int, positionDelete: Offset, widthDevice: Float, tmp: Boolean, onChange: (Boolean) -> Unit, width1: Dp, height1: Dp ) { val allowerDeleteApp by viewModel.allowerDeleteApp.collectAsState() val widthLeftContent by viewModel.widthLeftContent.collectAsState() val check = remember { mutableStateOf(0) } var lists = remember { mutableStateOf(list) } var listAppss = remember { mutableStateOf(listApps) } LaunchedEffect(tmp, listApps) { lists.value = list listAppss.value = listApps } val state = rememberReorderableLazyGridState(onMove = {from, to -> lists.value = lists.value.toMutableList().apply { val itemToMove = removeAt(from.index) add(to.index, itemToMove) } if (pagerState is PagerState) { listAppss.value = listAppss.value.toMutableList().apply { val itemToMove = removeAt(from.index + (pagerState.currentPage * 9)) add(to.index + (pagerState.currentPage * 9), itemToMove) check.value = check.value ++ } viewModel.setList(listAppss.value) } }) var boxPosition by remember { mutableStateOf(IntOffset.Zero) } var checkAllowDelete = remember { mutableStateOf(true) } LazyVerticalGrid( columns = GridCells.Fixed(5), state = state.gridState, verticalArrangement = Arrangement.spacedBy(50.dp1), horizontalArrangement = Arrangement.spacedBy(width1 * 0.12f), contentPadding = PaddingValues(horizontal = 30.dp, vertical = 10.dp), modifier = Modifier .reorderable(state) .fillMaxSize() .detectReorderAfterLongPress(state) ) { items(lists.value.size, { if (lists.value[it].icon == null) lists.value[it].pkgId else lists.value[it].icon!!.toString()}) { item -> val coroutineScope = rememberCoroutineScope() ReorderableItem(state, lists.value[item].icon.toString()) { isDragging -> if (isDragging) { viewModel._itemDelete.value = lists.value.get(item) viewModel._openDeleteApp.value = true viewModel._allowerDeleteApp.value = false if (boxPosition.x > widthDevice - 100) { if (pagerState is PagerState) { if (checkAllowDelete.value) { checkAllowDelete.value = false listAppss.value = listAppss.value.toMutableList().apply { val itemToMove = removeAt(item + ((pagerState.currentPage) * 9)) add(min(((pagerState.currentPage + 1) * 9), listAppss.value.size), itemToMove) } viewModel.setList(listAppss.value) coroutineScope.launch { pagerState.scrollToPage(pagerState.currentPage + 1) onChange(!tmp) } } } } else if (boxPosition.x < widthLeftContent && boxPosition.x != 0) { if (pagerState is PagerState) { if (pagerState.currentPage > 0) { if (checkAllowDelete.value) { checkAllowDelete.value = false listAppss.value = listAppss.value.toMutableList().apply { val itemToMove = removeAt(item + ((pagerState.currentPage) * 9)) add(min(0+ ((pagerState.currentPage - 1) * 9), listAppss.value.size), itemToMove) } viewModel.setList(listAppss.value) coroutineScope.launch { pagerState.scrollToPage(pagerState.currentPage - 1) onChange(!tmp) } } } } } else if (boxPosition.x < (positionDelete.x + width) && boxPosition.x > (positionDelete.x - width) && boxPosition.y < (positionDelete.y + height) && boxPosition.y > (positionDelete.y - height)) { viewModel._allowerDeleteApp.value = true } else { viewModel._allowerDeleteApp.value = false } } else { if (lists.value.get(item) == viewModel.itemDelete.value) { viewModel._openDeleteApp.value = false if (allowerDeleteApp) { viewModel._allowerDeleteApp.value = false viewModel.uninstallApp(context = context, packageName = lists.value.get(item).pkgId) } } } if (lists.value[item].icon == null) { Box(modifier = Modifier.fillMaxSize()) { } } else { Box( modifier = Modifier .fillMaxSize() .clickable { kotlin.runCatching { viewModel.startActivity(context, list[item]) } }) { Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally ) { Box(contentAlignment = Alignment.Center) { Image( painter = painterResource(id = R.drawable.ic_bg_app), contentDescription = "", modifier = Modifier.size(width1 * 0.1f) ) Image( painter = rememberDrawablePainter(drawable = lists.value[item].icon), contentDescription = "", modifier = Modifier .size(width1 * 0.065f) .padding(5.dp1) .onGloballyPositioned { coordinates -> if (isDragging == true) { boxPosition = IntOffset( x = coordinates.positionInWindow().x.toInt(), y = coordinates.positionInWindow().y.toInt() ) } } ) } Text( text = lists.value[item].title, modifier = Modifier.padding(top = 10.dp1, bottom = 10.dp1), maxLines = 1, overflow = TextOverflow.Ellipsis, style = TextStyle( color = Color.White, fontWeight = FontWeight.Bold, fontSize = 12.sp ) ) } } } } } } } @OptIn(ExperimentalFoundationApi::class) @Composable fun ListApps(list: List<AppPackage>, context: Context, viewModel: MainViewModel, height1: Dp) { LazyVerticalGrid( columns = GridCells.Adaptive(minSize = 128.dp) ) { items(list.size, { list[it].icon.toString() }) { index -> Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier .combinedClickable( onClick = { kotlin.runCatching { viewModel.startActivity(context, list[index]) } }, onLongClick = { viewModel.setModeEdit(true) }) ) { Box(contentAlignment = Alignment.Center) { Image( painter = painterResource(id = R.drawable.ic_bg_app), contentDescription = "", modifier = Modifier.size(height1 * 0.12f) ) Image( painter = rememberDrawablePainter(drawable = list[index].icon), contentDescription = "", modifier = Modifier.size(height1 * 0.1f) ) } Text( text = list[index].title, modifier = Modifier.padding(top = 10.dp1), maxLines = 1, overflow = TextOverflow.Ellipsis, style = TextStyle( color = Color.White, fontWeight = FontWeight.Bold ) ) } } } }
Editor is loading...
Leave a Comment