Skip to content

ibraheemzulfiqar/compose-instant

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 

Repository files navigation

Compose Instant

I might forget how to implement this later

Table of Contents

Easy Collapsing Toolbar

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Screen() {
    val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() // (1)

    Scaffold(
        modifier = Modifier
                   .nestedScroll(scrollBehavior.nestedScrollConnection), // (2)
        floatingActionButton = {
           // FAB
        },
        topBar = {
            TopAppBar(
                title = {
                    Text(text = "My APP", style = MaterialTheme.typography.titleLarge)
                },
                scrollBehavior = scrollBehavior, // (3)
                )
        }
    ) {
       // CONTENT
    }
}
    implementation 'androidx.compose.material3:material3'

Swipe to dismiss

🔗 Refrence Article

@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
inline fun <T> LazyListScope.swipeableItems(
    items: List<T>,
    modifier: Modifier = Modifier,
    noinline key: ((item: T) -> Any)? = null,
    noinline onStateChange: (state: DismissValue, item: T) -> Boolean,
    crossinline background: @Composable() (RowScope.(dismissState: DismissState) -> Unit) = {},
    noinline contentType: (item: T) -> Any? = { null },
    crossinline itemContent: @Composable LazyItemScope.(item: T) -> Unit,
) {
    items(
        items = items,
        key = key,
        contentType = contentType,
    ) { item ->
        val currentItem by rememberUpdatedState(newValue = item)
        val dismissState = rememberDismissState(
            confirmValueChange = { state ->
                onStateChange(state, currentItem)
            }
        )

        SwipeToDismiss(
            state = dismissState,
            background = {
                background(dismissState)
            },
            dismissContent = {
                itemContent(this@items, item)
            },
            modifier = modifier.animateItemPlacement(),
        )

    }
}

Usage:

    LazyColumn {
        swipeableItems(
            items = accounts,
            key = { it.id },
            onStateChange = { state, item ->
                false
            },
            background = {state ->
               // background
            }
        ) { item ->
            AccountItem(item, onAccountClick)
        }
    }
    implementation 'androidx.compose.material3:material3:1.2.0-alpha02'

To quickly add background:

@Composable
@OptIn(ExperimentalMaterial3Api::class)
fun EasySwipeableBackground(
    modifier: Modifier = Modifier,
    scaleOnDismiss: Float = 1.5f,
    dismissState: DismissState,
    backgrounds: SwipeableItemBackgrounds,
    startIcon: SwipeableItemIcon,
    endIcon: SwipeableItemIcon
) {

    val direction = dismissState.dismissDirection ?: return

    val backgroundColor by animateColorAsState(
        when (dismissState.targetValue) {
            DismissValue.Default -> backgrounds.defaultColor
            DismissValue.DismissedToEnd -> backgrounds.dismissedToEndColor
            DismissValue.DismissedToStart -> backgrounds.dismissedToStartColor
        }
    )

    val startIconColor by animateColorAsState(
        when (dismissState.targetValue) {
            DismissValue.Default -> startIcon.defaultColor
            DismissValue.DismissedToEnd -> startIcon.dismissedColor
            DismissValue.DismissedToStart -> startIcon.dismissedColor
        }
    )

    val endIconColor by animateColorAsState(
        when (dismissState.targetValue) {
            DismissValue.Default -> endIcon.defaultColor
            DismissValue.DismissedToEnd -> endIcon.dismissedColor
            DismissValue.DismissedToStart -> endIcon.dismissedColor
        }
    )

    val iconColor = when (direction) {
        DismissDirection.StartToEnd -> startIconColor
        DismissDirection.EndToStart -> endIconColor
    }

    val alignment = when (direction) {
        DismissDirection.StartToEnd -> Alignment.CenterStart
        DismissDirection.EndToStart -> Alignment.CenterEnd
    }

    val icon = when (direction) {
        DismissDirection.StartToEnd -> startIcon.icon
        DismissDirection.EndToStart -> endIcon.icon
    }
    val scale by animateFloatAsState(
        if (dismissState.targetValue == DismissValue.Default) 1f else scaleOnDismiss,
        animationSpec = spring(dampingRatio = Spring.DampingRatioHighBouncy)
    )

    Box(
        modifier
            .fillMaxSize()
            .background(backgroundColor)
            .padding(horizontal = 20.dp),
        contentAlignment = alignment
    ) {
        Icon(
            icon,
            contentDescription = "",
            modifier = Modifier.scale(scale),
            tint = iconColor
        )
    }
}
data class SwipeableItemBackgrounds(
    val defaultColor: Color,
    val dismissedToEndColor: Color,
    val dismissedToStartColor: Color,
)

data class SwipeableItemIcon(
    val defaultColor: Color,
    val dismissedColor: Color,
    val icon: ImageVector
)

Usage:

EasySwipeableBackground(
    dismissState = state,
    backgrounds = SwipeableItemBackgrounds(MaterialTheme.colorScheme.surface, Color.Yellow, Color.Red),
    startIcon = SwipeableItemIcon(Color.Yellow, Color.Black, Icons.Default.Star),
    endIcon = SwipeableItemIcon(Color.Red, Color.Black, Icons.Default.Delete)
)