Sag*_*tus 12 android kotlin android-jetpack-compose
我正在使用ModalBottomSheet并且必须State hoisting使用它的祖先组件。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Demo4Theme {
// A surface container using the 'background' color from the theme
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
ArticleScreen()
}
}
}
}
}
@Stable
class ArticleState(
val orderModalState: SageSheetState,
val filterModalState: DrawerState
)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun rememberSageSheetState(
state: SageSheetState = SageSheetState(
coroutineScope = rememberCoroutineScope(), sheetState = rememberSheetState()
)): SageSheetState {
return remember { state }
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun rememberArticleState(
orderModalState: SageSheetState = rememberSageSheetState(),
filterModalState: DrawerState = rememberDrawerState(DrawerValue.Closed)
): ArticleState {
return remember {
ArticleState(
orderModalState = orderModalState,
filterModalState = filterModalState
)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ArticleScreen(
state: ArticleState = rememberArticleState()
) {
Column {
Text("${state.orderModalState.sheetState.currentValue}")
Text("${state.orderModalState.sheetState.isVisible}")
Text("${state.orderModalState.sheetState.targetValue}")
Button(onClick = { state.orderModalState.showModal() }) {
Text("Show Modal")
}
}
Modal(
modalState = state.orderModalState,
)
}
@OptIn(ExperimentalMaterial3Api::class)
class SageSheetState(
private val coroutineScope: CoroutineScope,
val sheetState: SheetState,
openBottomSheet: Boolean = false
) {
var openBottomSheet by mutableStateOf(openBottomSheet)
fun showModal() {
coroutineScope.launch {
openBottomSheet = true
sheetState.collapse()
}
}
fun closeModal() {
coroutineScope.launch {
sheetState.hide()
openBottomSheet = false
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Modal(
modalState: SageSheetState
) {
// Sheet content
if (modalState.openBottomSheet) {
ModalBottomSheet(
onDismissRequest = { modalState.closeModal() },
sheetState = modalState.sheetState,
) {
Text("Hello")
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我点击按钮时Show Modal,就出错了。
The offset was read before being initialized. Did you access the offset in a phase before layout, like effects or composition?
Run Code Online (Sandbox Code Playgroud)
我不知道我哪里做错了,也许使用State hoisting方式错误,官方示例工作正常(状态保存本身)。
- 我正在使用最新版本的 Compose Material3
androidx.compose.material3:material3:1.1.0-alpha06- 如果要运行该项目,您可能需要修改存储库设置。
小智 1
您可以使用 DisposableEffect 来确保仅在布局阶段之后调用 showModal 和 closeModal 函数。
@OptIn(ExperimentalMaterial3Api::class)
class SageSheetState(
private val coroutineScope: CoroutineScope,
val sheetState: SheetState,
openBottomSheet: Boolean = false
) {
var openBottomSheet by mutableStateOf(openBottomSheet)
private set
fun showModal() {
coroutineScope.launch {
openBottomSheet = true
sheetState.collapse()
}
}
fun closeModal() {
coroutineScope.launch {
sheetState.hide()
openBottomSheet = false
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Modal(
modalState: SageSheetState
) {
DisposableEffect(modalState.openBottomSheet) {
onDispose { }
}
// Sheet content
if (modalState.openBottomSheet) {
ModalBottomSheet(
onDismissRequest = { modalState.closeModal() },
sheetState = modalState.sheetState,
) {
Text("Hello")
}
}
}
Run Code Online (Sandbox Code Playgroud)