繁体   English   中英

为什么 SwipeToDismiss 在 Jetpack Compose 中抛出 NoSuchElementException?

[英]Why SwipeToDismiss throws NoSuchElementException in Jetpack Compose?

问题视频: https://youtu.be/4Q7JpYfaJgw

如果我们向右推几次 SwipeToDismiss 元素,它将引发异常。 它导致当我想使用progress.fraction作为Imagealpha时。 如果相乘的数字更大,错误会发生得更快。

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.dewerro.myapplication.ui.theme.MyApplicationTheme

@ExperimentalMaterialApi
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val items = arrayListOf("hi", "everyone", "this", "is", "example", "of", "my", "problem")
        setContent {
            MyApplicationTheme {
                Surface(color = MaterialTheme.colors.background) {
                    LazyColumn {
                        items(items.size) { index ->
                            val dismissState = rememberDismissState()

                            SwipeToDismiss(
                                state = dismissState,
                                modifier = Modifier.clip(RoundedCornerShape(17.dp)),
                                background = {
                                    Row(
                                        modifier = Modifier.fillMaxSize(),
                                        horizontalArrangement = Arrangement.End
                                    ) {
                                        Image(
                                            painter = painterResource(R.drawable.app_products_screen_trash_box),
                                            contentDescription = "Trash box icon",
                                            alpha = dismissState.progress.fraction * 1.8F // <- exception in this string
                                        )
                                    }
                                },
                                dismissContent = {
                                    ProductsItem(
                                        text = items[index],
                                        modifier = Modifier
                                            .width(300.dp)
                                            .animateContentSize()
                                    )
                                },
                                directions = setOf(DismissDirection.EndToStart)
                            )
                            Spacer(modifier = Modifier.height(16.dp))
                        }
                    }
                }
            }
        }
    }
}
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowDropDown
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Color.Companion.Blue
import androidx.compose.ui.graphics.Color.Companion.White
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

@ExperimentalMaterialApi
@Composable
fun ProductsItem(
    modifier: Modifier,
    text: String
) {
    var expandedState by remember { mutableStateOf(false) }
    val rotationState by animateFloatAsState(
        targetValue = if (expandedState) 180F else 0F
    )

    Card(
        modifier = modifier,
        backgroundColor = Blue,
        shape = RoundedCornerShape(17.dp)
    ) {
        Column {
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.End
            ) {
                Text(
                    text = text,
                    modifier = Modifier
                        .width(250.dp)
                        .padding(start = 5.dp),
                    color = White,
                    fontWeight = FontWeight.Normal,
                    fontSize = 25.sp,
                    textAlign = TextAlign.Start
                )
                IconButton(
                    modifier = Modifier
                        .alpha(ContentAlpha.medium)
                        .rotate(rotationState),
                    onClick = {
                        expandedState = !expandedState
                    }) {
                    Icon(
                        imageVector = Icons.Default.ArrowDropDown,
                        contentDescription = "Drop-Down Arrow"
                    )
                }
            }
            if (expandedState) {
                Text(
                    text = "Example",
                    color = White,
                    modifier = Modifier.padding(start = 5.dp, bottom = 5.dp),
                    fontSize = 15.sp,
                    fontWeight = FontWeight.Normal,
                    maxLines = 3,
                    overflow = TextOverflow.Ellipsis
                )
            }
        }
    }
}
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.dewerro.myproducts, PID: 4329
    java.util.NoSuchElementException: Key 8.983873E-4 is missing in the map.
        at kotlin.collections.MapsKt__MapWithDefaultKt.getOrImplicitDefaultNullable(MapWithDefault.kt:24)
        at kotlin.collections.MapsKt__MapsKt.getValue(Maps.kt:344)
        at androidx.compose.material.SwipeableState.getProgress(Swipeable.kt:275)
        at com.dewerro.myproductsapp.my_products.presentation.products.ProductsScreenKt$ProductsScreen$2$4$2$2$1.invoke(ProductsScreen.kt:123)
        at com.dewerro.myproductsapp.my_products.presentation.products.ProductsScreenKt$ProductsScreen$2$4$2$2$1.invoke(ProductsScreen.kt:115)
        at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116)
        at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$1.invoke(ComposableLambda.jvm.kt:127)
        at androidx.compose.runtime.internal.ComposableLambdaImpl$invoke$1.invoke(ComposableLambda.jvm.kt:127)
        at androidx.compose.runtime.RecomposeScopeImpl.compose(RecomposeScopeImpl.kt:140)
        at androidx.compose.runtime.ComposerImpl.recomposeToGroupEnd(Composer.kt:2156)
        at androidx.compose.runtime.ComposerImpl.skipCurrentGroup(Composer.kt:2399)
        at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:2580)
        at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:2566)
        at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(SnapshotState.kt:540)
        at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:2566)
        at androidx.compose.runtime.ComposerImpl.recompose$runtime_release(Composer.kt:2542)
        at androidx.compose.runtime.CompositionImpl.recompose(Composition.kt:614)
        at androidx.compose.runtime.Recomposer.performRecompose(Recomposer.kt:764)
        at androidx.compose.runtime.Recomposer.access$performRecompose(Recomposer.kt:103)
        at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:447)
        at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2$2.invoke(Recomposer.kt:416)
        at androidx.compose.ui.platform.AndroidUiFrameClock$withFrameNanos$2$callback$1.doFrame(AndroidUiFrameClock.android.kt:34)
        at androidx.compose.ui.platform.AndroidUiDispatcher.performFrameDispatch(AndroidUiDispatcher.android.kt:109)
        at androidx.compose.ui.platform.AndroidUiDispatcher.access$performFrameDispatch(AndroidUiDispatcher.android.kt:41)
        at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.doFrame(AndroidUiDispatcher.android.kt:69)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:970)
        at android.view.Choreographer.doCallbacks(Choreographer.java:796)
        at android.view.Choreographer.doFrame(Choreographer.java:727)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

如果需要图片:

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="45dp"
    android:height="44dp"
    android:viewportWidth="45"
    android:viewportHeight="44">
  <path
      android:pathData="M9.8438,9.625L11.6016,37.125C11.6851,38.714 12.8672,39.875 14.4141,39.875H30.5859C32.139,39.875 33.2991,38.714 33.3984,37.125L35.1562,9.625"
      android:strokeLineJoin="round"
      android:strokeWidth="2"
      android:fillColor="#00000000"
      android:strokeColor="#FD0505"
      android:strokeLineCap="round"/>
  <path
      android:pathData="M7.0313,9.625H37.9688Z"
      android:fillColor="#FD0505"/>
  <path
      android:pathData="M7.0313,9.625H37.9688"
      android:strokeWidth="2"
      android:fillColor="#00000000"
      android:strokeColor="#FD0505"
      android:strokeLineCap="round"/>
  <path
      android:pathData="M28.8281,15.125L28.125,34.375M16.875,9.625V6.1875C16.8742,5.9164 16.9282,5.6479 17.0339,5.3973C17.1396,5.1467 17.295,4.919 17.491,4.7273C17.687,4.5356 17.9199,4.3838 18.1762,4.2804C18.4325,4.177 18.7071,4.1242 18.9844,4.125H26.0156C26.2929,4.1242 26.5675,4.177 26.8238,4.2804C27.0801,4.3838 27.313,4.5356 27.509,4.7273C27.705,4.919 27.8604,5.1467 27.9661,5.3973C28.0718,5.6479 28.1258,5.9164 28.125,6.1875V9.625H16.875ZM22.5,15.125V34.375V15.125ZM16.1719,15.125L16.875,34.375L16.1719,15.125Z"
      android:strokeLineJoin="round"
      android:strokeWidth="2"
      android:fillColor="#00000000"
      android:strokeColor="#FD0505"
      android:strokeLineCap="round"/>
</vector>

这是一个已知问题,star 以获得更多关注,然后它会更快得到解决。

由于它只发生在接近零的值时,我认为在它被修复之前捕获它或多或少是安全的:

val progress = try {
    dismissState.progress.fraction
} catch (_: Throwable) {
    0f
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM