【发布时间】:2023-01-23 13:27:41
【问题描述】:
我试图在我制作的测试应用程序中将我的旧 XML 布局转换为 @Composable 类,但我在“加载”屏幕上遇到了问题。
该应用程序有一个按钮,可以从免费 API 获取报价,点击后,页面顶部会出现一个加载屏幕,有效阻止与该按钮的进一步交互。 加载屏幕以前是 RelativeLayout,里面有一个 ProgressBar。
现在使用 Compose,我无法设法让这个加载屏幕“位于顶部”,因为按钮仍然显示在它上面并保持可点击。
使用 MaterialButtons 时,同样的“错误”行为也可以通过 XML 布局重现,而使用 AppCompatButtons 则问题得到解决。
有没有办法在撰写中完成这项工作?
附:这是我的 Compose 解决方案
@Composable
fun QuoteButton(text: String, onClick: () -> Unit) {
Button(
onClick,
shape = RoundedCornerShape(20.dp),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 20.dp, vertical = 5.dp)
) {
Text(text = text)
}
}
@Composable
fun QuoteLoading(
isLoading: MutableState<Boolean>,
content: @Composable () -> Unit
) = if (isLoading.value) {
Box(
Modifier
.fillMaxSize()
.background(Color.Black.copy(alpha = 0.3f))
.pointerInput(Unit) {}
) {
CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
}
content()
} else {
content()
}
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
QuoteLoading(isLoading = loadingState) {
Column {
QuoteDisplay(textState)
QuoteButton(getString(R.string.button_fetch_quote)) {
viewModel.setEvent(Event.GetQuote)
}
QuoteButton(getString(R.string.button_save_quote)) {
viewModel.setEvent(Event.SaveQuote)
}
QuoteButton(getString(R.string.button_clear_quotes)) {
viewModel.setEvent(Event.ClearQuote)
}
}
}
}
}
}
}
}
private val DarkColorPalette = darkColors(
primary = Color(0xFFBB86FC),
primaryVariant = Color(0xFF3700B3),
secondary = Color(0xFF03DAC5)
)
private val LightColorPalette = lightColors(
primary = Color(0xFF6200EE),
primaryVariant = Color(0xFF3700B3),
secondary = Color(0xFF03DAC5)
)
@Composable
fun ComposeTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {
MaterialTheme(
colors = if (darkTheme) DarkColorPalette else LightColorPalette,
content = content
)
}
【问题讨论】:
-
您的框位于内容下方,这就是它不会阻挡指针的原因。您只需要交换视图顺序。此外,像在
QuoteLoading中那样构建包装器也是一种不好的做法,因为content将被重新创建。为了使其重用,您必须在两种情况下使用相同的视图,而不是在每个if案例中创建一个新视图,例如 this -
我想你可以删除这个问题,因为任何有同样问题的人都不可能找到它。
-
非常感谢 Philip 的回答,我是 Compose 的新手,还有很多东西要学。顺便说一下,您的 Gist 是同时解决“备注”(我的意思是订单放置和包装)还是仅解决订单问题?如何解决包装器的不良做法?
-
是的,它解决了两个问题。如果您有任何用
@Composable注释的参数,例如content,它应该只被调用一次。
标签: android android-jetpack-compose android-button android-jetpack