我有一个自定义键,我想在点击时使用涟漪效果,涟漪效果默认添加到.clickable中,但我想要有onClick onLongClick和onPress的PointerInput,所以我如何在保留这些效果的同时实现涟漪效果. 这是我的CustomKey可组合的.

package com.soloftech.keyboard.presentation.layout


import android.content.Context
import android.os.Vibrator
import android.view.inputmethod.EditorInfo
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.constraintlayout.compose.ConstraintLayout
import com.soloftech.keyboard.R
import com.soloftech.keyboard.domain.keyboard.Key
import com.soloftech.keyboard.domain.playSound
import com.soloftech.keyboard.domain.showPopUp
import com.soloftech.keyboard.domain.vibrate

@Composable
fun CustomKey(
    key: Key,
    isCapsLockEnabled: Boolean = false,
    onKeyPressed: (Key) -> Unit,
    onLongKeyPressed: (Key) -> Unit,
    onLongKeyPressedEnd: () -> Unit,
    modifier: Modifier,
    onLayoutSwitchClick: () -> Unit,
    onExtendedSymbolsSwitchClick: () -> Unit,
    onNumbersSwitchClick: () -> Unit,
    onSymbolsLayoutSwitchClick: () -> Unit,
    onCapsClick: () -> Unit,
    context: Context?,
    vibrator: Vibrator? = null,
    iconResourceId: Int = key.icon,
    textColor: Color = colorResource(id = R.color.KeyTextColor),
    imeAction: Int? = null
) {

    val isPopupVisible = remember { mutableStateOf(false) }

    val keyColor = if (key.isSpecialCharacter) {
        colorResource(id = R.color.SpecialKeyBackground)
    } else {
        colorResource(id = R.color.KeyBackground)
    }

    val keyShape = when (key.labelMain) {
        "?123", "Done", "ABC" -> RoundedCornerShape(36.dp)
        else -> RoundedCornerShape(6.dp)
    }

    val labelMain = remember(key.labelMain, isCapsLockEnabled) {
        if (isCapsLockEnabled) {
            key.labelMain.uppercase()
        } else {
            key.labelMain
        }
    }


    val icon = when (key.labelMain) {
        "CAPS" -> {
            if (isCapsLockEnabled) {
                R.drawable.caps_lock_on
            } else {
                R.drawable.caps_lock_off
            }
        }

        "Done" -> {
            when (imeAction) {
                EditorInfo.IME_ACTION_DONE -> R.drawable.done_icon
                EditorInfo.IME_ACTION_SEARCH -> R.drawable.search_icon
                EditorInfo.IME_ACTION_NEXT -> R.drawable.next_icon
                EditorInfo.IME_ACTION_SEND -> R.drawable.send_icon
                EditorInfo.IME_ACTION_GO -> R.drawable.go_icon
                EditorInfo.IME_ACTION_NONE -> R.drawable.keyboard_return
                EditorInfo.IME_ACTION_PREVIOUS -> R.drawable.previous_icon
                else -> key.icon
            }
        }

        else -> iconResourceId
    }

    var isLongPressed by remember {
        mutableStateOf(false)
    }


    val popUpLabel = if (isLongPressed) key.labelSecondary ?: "" else key.labelMain

    ConstraintLayout(
        modifier = modifier
            .clip(keyShape)
            .background(color = keyColor)
            .pointerInput(Unit) {
                detectTapGestures(
                    onTap = {
                        onClick(
                            isPopupVisible = isPopupVisible,
                            context = context,
                            vibrator = vibrator
                        )
                        when (key.labelMain) {
                            "ABC" -> onLayoutSwitchClick()
                            "?123" -> onSymbolsLayoutSwitchClick()
                            "=\\<" -> onExtendedSymbolsSwitchClick()
                            "!?#" -> onSymbolsLayoutSwitchClick()
                            "Numbers" -> onNumbersSwitchClick()
                            "CAPS" -> {
                                onCapsClick()
                            }

                            else -> onKeyPressed(key)
                        }
                    },
                    onLongPress = {
                        onClick(
                            isPopupVisible = isPopupVisible,
                            context = context,
                            vibrator = vibrator
                        )
                        isLongPressed = true
                        onLongKeyPressed(key)
                    },
                    onPress = {
                        awaitRelease()
                        onLongKeyPressedEnd()
                        isLongPressed = false
                    }
                )
            }
                
            .defaultMinSize(minHeight = dimensionResource(id = R.dimen.key_height).value.dp)
    ) {
        if (key.shouldShowIcon) {
            Icon(
                painter = painterResource(id = icon),
                contentDescription = key.contentDescription,
                tint = textColor,
                modifier = Modifier
                    .constrainAs(createRef()) {
                        top.linkTo(parent.top)
                        bottom.linkTo(parent.bottom)
                        start.linkTo(parent.start)
                        end.linkTo(parent.end)
                    }
            )
        } else {
            when (key.labelMain) {
                "?123", "ABC", "Space", "!?#" -> AutoResizedText(
                    text = key.labelMain,
                    color = textColor,
                    modifier = Modifier.constrainAs(createRef()) {
                        top.linkTo(parent.top)
                        bottom.linkTo(parent.bottom)
                        start.linkTo(parent.start)
                        end.linkTo(parent.end)
                    }
                )

                else -> Text(
                    text = labelMain,
                    color = textColor,
                    fontSize = dimensionResource(id = R.dimen.key_textSize).value.sp,
                    fontWeight = FontWeight.Medium,
                    modifier = Modifier.constrainAs(createRef()) {
                        top.linkTo(parent.top)
                        bottom.linkTo(parent.bottom)
                        start.linkTo(parent.start)
                        end.linkTo(parent.end)
                    }
                )
            }
        }
        if (key.shouldShowPopUp) {
            PopupScreen(
                label = popUpLabel,
                offset = IntOffset(x = 0, y = -50),
                isVisible = isPopupVisible.value
            )
        }
        key.labelSecondary?.let {
            Text(
                text = it,
                color = textColor,
                fontSize = dimensionResource(id = R.dimen.key_textHintSize).value.sp,
                modifier = Modifier
                    .constrainAs(createRef()) {
                        top.linkTo(parent.top, margin = 2.dp)
                        end.linkTo(parent.end, margin = 2.dp)
                    }
            )
        }
    }
}

@Preview
@Composable
fun CustomKeyPreview() {
    CustomKey(
        key = Key("f", 1F, labelSecondary = "@"),
        onKeyPressed = {},
        onLongKeyPressed = {},
        onLongKeyPressedEnd = {},
        modifier = Modifier,
        onLayoutSwitchClick = {},
        onExtendedSymbolsSwitchClick = {},
        onSymbolsLayoutSwitchClick = { },
        onCapsClick = {},
        onNumbersSwitchClick = {},
        context = null
    )
}

fun onClick(
    isPopupVisible: MutableState<Boolean>,
    context: Context?,
    vibrator: Vibrator?
) {
    showPopUp(isPopupVisible)
    if (context != null) {
        playSound(context = context)
    }
    vibrate(vibrator)
}

如何添加涟漪效果.谢谢

推荐答案

你可以这样做

// This is for emitting press or release event
val interactionSource = remember { MutableInteractionSource() }

val pointerModifier = Modifier
    // other modifiers
    .indication(interactionSource, rememberRipple())
    .pointerInput(Unit) {
        detectTapGestures(
            onPress = { offset: Offset ->
                val press = PressInteraction.Press(offset)
                interactionSource.emit(press)
                // Waits for the press to be released before returning.
                // If the press was released, true is returned, or if the gesture
                // was canceled by motion being consumed by another gesture, false is returned.
                tryAwaitRelease()
                // We emit a release press interaction here
                interactionSource.emit(PressInteraction.Release(press))

            },
        )
    }

Android相关问答推荐

如何使用单个代码库使用不同的firebase项目创建多个应用程序ID apk

道查询注释部分房间表名称

懒惰列的滚动到项目不按预期工作'

在不增加父行宽度的情况下添加延迟行或可滚动行

如何在Android Jetpack Compose中找到我的手机屏幕一行有多少个单词

StateFlow和LazyColumn重组

在柯特林连续测量网速

Android布局渲染问题

Jetpack Compose中尺寸不断增加的动画

在Jetpack Compose中实现自动换行

为什么它显示我的空白屏幕?

错误:无法安装应用程序:INSTALL_PARSE_FAILED_MANIFEST_MALFORMED (React-Native-Android-Studio)

Jetpack Compose:在屏幕外制作长水平图像的动画

修复错误 Invariant Violation: requireNativeComponent: "RNSScreenStackHeaderConfig" was not found in the UIManager

在 Jetpack Compose 的无状态 Compose 中管理条件逻辑

我该怎么做文本计时器

JetPack Compose - 卡片行中的权重()不起作用

如何使用 ConstraintLayout 链接两个文本

为什么在try 实例化 Mediaplayer 时会出现 NullPointerException?安卓Kotlin

Android Jetpack Compose:如何让文本利用完整的行空间并将单词换行以防溢出?