我有一个自定义的WebView合成功能,我想在加载页面时显示自定义进度条,但它给出了这个错误。
Functions which invoke @Composable functions must be marked with the @Composable annotation
这是我的组合。
package com.example.devdocs
import android.graphics.Bitmap
import android.view.ViewGroup
import android.webkit.WebChromeClient
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView
@Composable
fun webView(
url: String = "www.google.com"
) {
var backEnabled by remember { mutableStateOf(false) }
var webView: WebView? = null
AndroidView(
factory = { context ->
WebView(context).apply {
settings.javaScriptEnabled = true
settings.userAgentString
settings.domStorageEnabled
settings.setSupportZoom(true)
settings.builtInZoomControls = true
settings.displayZoomControls = false
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView, url: String?, favicon: Bitmap?) {
backEnabled = view.canGoBack()
LoadingAnimation(
modifier = Modifier
.fillMaxWidth(),
isVisible = true
)
}
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
LoadingAnimation(
modifier = Modifier
.fillMaxWidth(),
isVisible = false
)
}
}
webChromeClient = WebChromeClient()
loadUrl(url)
webView = this
}
}, update = {
webView = it
})
BackHandler(enabled = backEnabled) {
webView?.goBack()
}
}
“LoadingAnimation”是一个显示动画的自定义动画类。下面是动画类源代码。
package com.example.devdocs
import androidx.compose.animation.core.*
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.delay
@Composable
fun LoadingAnimation(
modifier: Modifier = Modifier,
circleSize: Dp = 25.dp,
circleColor: Color = MaterialTheme.colorScheme.primary,
spaceBetween: Dp = 10.dp,
travelDistance: Dp = 20.dp,
isVisible: Boolean = true
) {
if (isVisible) {
val circles = listOf(
remember { Animatable(initialValue = 0f) },
remember { Animatable(initialValue = 0f) },
remember { Animatable(initialValue = 0f) }
)
circles.forEachIndexed { index, animatable ->
LaunchedEffect(key1 = animatable) {
delay(index * 100L)
animatable.animateTo(
targetValue = 1f,
animationSpec = infiniteRepeatable(
animation = keyframes {
durationMillis = 1200
0.0f at 0 with LinearOutSlowInEasing
1.0f at 300 with LinearOutSlowInEasing
0.0f at 600 with LinearOutSlowInEasing
0.0f at 1200 with LinearOutSlowInEasing
},
repeatMode = RepeatMode.Restart
)
)
}
}
val circleValues = circles.map { it.value }
val distance = with(LocalDensity.current) { travelDistance.toPx() }
Row(
modifier = modifier,
horizontalArrangement = Arrangement.spacedBy(spaceBetween)
) {
circleValues.forEach { value ->
Box(
modifier = Modifier
.size(circleSize)
.graphicsLayer {
translationY = -value * distance
}
.background(
color = circleColor,
shape = CircleShape
)
)
}
}
}
}
我该怎么解决这个问题?谢谢。
1条答案
按热度按时间bvjveswy1#
错误**@可组合函数只能从其他@可组合函数调用,表示只能从另一个可组合上下文中调用可组合函数。
在您的代码中,“LoadingAnimation”是一个可组合函数,它是从非可组合上下文调用的
您需要在页面开始/结束时显示/隐藏可组合UI。实现此目的的最佳方法是使用带有remember函数的MutableState**对象
请检查以下重构代码
你需要把自定义进度条放在webview的顶部,所以有几种方法可以做到这一点,我目前在这里使用box。
自定义进度条的代码(您可以在此处使用自己的自定义进度)