用Jetpack Compose做一个侧滑控件的功能

该代码实现了一个名为SideslipComposeView的Composable函数,用于在Android应用中为UI控件添加侧滑功能。它接受参数如宽度、高度、间隔和内容,使用AndroidXCompose的SwipeableState进行交互,并提供了恢复初始状态的控制。
摘要由CSDN通过智能技术生成
package com.zerone.qsg.ui.view

import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

/**
 * author: yetld
 * date: 2023/7/27
 */

/**
 * 给控件添加侧滑功能
 * @param blockWidth 宽
 * @param blockHeight 高
 * @param leftSpace 侧滑按钮与原控件中间的间隔
 * @param blockContent 侧滑按钮, 宽高要和blockWidth和blockHeight一致
 * @param itemContent 原控件
 * @param restTrigger 重置状态控制器   restTrigger.value = true 恢复状态
 */
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun SideslipComposeView(
    itemPadding: PaddingValues = PaddingValues(0.dp),
    blockWidth: Dp = 80.dp,
    blockHeight: Dp = 64.dp,
    leftSpace: Dp = 10.dp,
    itemContent: @Composable () -> Unit,
    blockContent: @Composable () -> Unit,
    restTrigger: MutableState<Boolean> = mutableStateOf(false)
) {
    val blockSizePx = with(LocalDensity.current) { (leftSpace + blockWidth).toPx() }
    val sideslipState = rememberSwipeableState(initialValue = State.ClOSS)
    val anchors = mapOf(
        0f to State.ClOSS,
        -blockSizePx to State.OPEN
    )
    val thresholds: (State, State) -> ThresholdConfig = { from, _ ->
        if (from == State.ClOSS) {
            FractionalThreshold(0.3f)
        } else {
            FractionalThreshold(0.5f)
        }
    }
    LaunchedEffect(restTrigger.value) {
        if (restTrigger.value) {
            withContext(Dispatchers.Main) {
                sideslipState.animateTo(targetValue = State.ClOSS)
            }
            restTrigger.value = false
        }
    }
    Box(
        modifier = Modifier
            .padding(paddingValues = itemPadding)
            .height(blockHeight)
            .fillMaxWidth()
    ) {
        Box(modifier = Modifier
            .offset { IntOffset(sideslipState.offset.value.toInt(), 0) }
            .swipeable(
                state = sideslipState,
                anchors = anchors,
                thresholds = thresholds,
                orientation = Orientation.Horizontal
            )
            .fillMaxWidth()
            .height(blockHeight)
            .clip(RoundedCornerShape(12.dp))
        ) {
            itemContent()
        }

        Row(
            modifier = Modifier
                .offset {
                    IntOffset(
                        (leftSpace + blockWidth)
                            .toPx()
                            .toInt() + sideslipState.offset.value.toInt(),
                        0
                    )
                }
                .size(leftSpace + blockWidth, blockHeight)
                .align(Alignment.CenterEnd)
        ) {
            Spacer(
                modifier = Modifier
                    .width(leftSpace)
            )
            blockContent()
        }
    }
}

private enum class State {
    ClOSS, OPEN
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值