ModalBottomSheetLayout在Jetpack Compose中无法再次打开。

huangapple go评论57阅读模式
英文:

ModalBottomSheetLayout not opening again in jetpack compose

问题

I was learning ModalBottomSheetLayout in my project. I have a Button and onClick I am sending Boolean to show sheetContent. It works once without any problem. After clicking on outside of ModalBottomSheetLayout it closes the sheetContent. After again clicking on `Button, sheet is not opening again. I don't understand what is the problem in here.

MainActivity.kt

class MainActivity : AppCompatActivity() {

    private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
    private val viewModel by viewModels<MainActivityViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        viewModel.enableBottomSheet.observe(this) {
            binding.bottomSheetComposeView.setContent {
                ModalBottomSheetSample(it)
            }
        }

        binding.buttonComposeView.setContent {
            ButtonView()
        }
    }

    @Composable
    fun ButtonView() {
        Column(Modifier.fillMaxSize()) {
            Button(onClick = {
                viewModel.enableBottomSheet.postValue(true)
            }) {
                Text(text = "Open Bottom Sheet")
            }
        }
    }

    @Composable
    @OptIn(ExperimentalMaterialApi::class)
    fun ModalBottomSheetSample(value: Boolean) {
        val state = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden, skipHalfExpanded = true)
        val scope = rememberCoroutineScope()
        SideEffect {
            scope.launch {
                if (value) {
                    state.show()
                }
            }
        }
        ModalBottomSheetLayout(
            sheetState = state,
            sheetContent = {
                LazyColumn {
                    items(5) {
                        ListItem(
                            icon = {
                                Icon(
                                    Icons.Default.Favorite,
                                    contentDescription = null
                                )
                            },
                            text = { Text("Item $it") },
                        )
                    }
                }
            }
        ) {}
    }

}

**MainActivityViewModel.kt**

```kotlin
class MainActivityViewModel : ViewModel() {
    val enableBottomSheet by lazy { MutableLiveData(false) }
}

Output

Here in this video, you can clearly see 1st time open the Bottom sheet on Button click. But not open for next click. Thanks

I am using compose_bom = "2023.03.00". Please don't suggested alpha or beta fix.

英文:

I was learning ModalBottomSheetLayout in my project. I have a Button and onClick I am sending Boolean to show sheetContent. It works once without any problem. After clicking on outside of ModalBottomSheetLayout it closes the sheetContent. After again clicking on `Button, sheet is not opening again. I don't understand what is the problem in here.

MainActivity.kt

class MainActivity : AppCompatActivity() {

    private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
    private val viewModel by viewModels&lt;MainActivityViewModel&gt;()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

        viewModel.enableBottomSheet.observe(this) {
            binding.bottomSheetComposeView.setContent {
                ModalBottomSheetSample(it)
            }
        }

        binding.buttonComposeView.setContent {
            ButtonView()
        }
    }

    @Composable
    fun ButtonView() {
        Column(Modifier.fillMaxSize()) {
            Button(onClick = {
                viewModel.enableBottomSheet.postValue(true)
            }) {
                Text(text = &quot;Open Bottom Sheet&quot;)
            }
        }
    }

    @Composable
    @OptIn(ExperimentalMaterialApi::class)
    fun ModalBottomSheetSample(value: Boolean) {
        val state = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden, skipHalfExpanded = true)
        val scope = rememberCoroutineScope()
        SideEffect {
            scope.launch {
                if (value) {
                    state.show()
                }
            }
        }
        ModalBottomSheetLayout(
            sheetState = state,
            sheetContent = {
                LazyColumn {
                    items(5) {
                        ListItem(
                            icon = {
                                Icon(
                                    Icons.Default.Favorite,
                                    contentDescription = null
                                )
                            },
                            text = { Text(&quot;Item $it&quot;) },
                        )
                    }
                }
            }
        ) {}
    }

}

MainActivityViewModel.kt

class MainActivityViewModel : ViewModel() {
    val enableBottomSheet by lazy { MutableLiveData(false) }
}

Output

Here in this video, you can clearly see 1st time open the Bottom sheet on Button click. But not open for next click. Thanks

I am using compose_bom = &quot;2023.03.00&quot;. Please don't suggested alpha or beta fix.

答案1

得分: 0

Here is the translated content you requested:

我做了两个更改

1. 更改函数的状态即将`StateFul`和`StateLess`分开
2. 从`LiveData`更改为`MutableSharedFlow`它正常工作

**MainActivityViewModel.kt**

```kotlin
class MainActivityViewModel : ViewModel() {
    val showBottomSheetContent by lazy { MutableSharedFlow<Boolean>() }
}

MainActivity.kt

class MainActivity : AppCompatActivity(), HideViewListener {

    private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
    private val viewModel by viewModels<MainActivityViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.showBottomSheetContent
                    .collect { value ->
                        binding.bottomSheetComposeView.setContent {
                            ModalBottomSheetSample(value)
                        }
                    }
            }
        }

        binding.buttonComposeView.setContent {
            ButtonViewContent()
        }
    }

    @Composable
    fun ButtonViewContent() {
        val scope = rememberCoroutineScope()
        Column(Modifier.fillMaxSize()) {
            Button(
                onClick = {
                    scope.launch {
                        viewModel.showBottomSheetContent.emit(true)
                    }
                }
            ) {
                Text(text = "打开底部工作表")
            }
        }
    }

    @Composable
    @OptIn(ExperimentalMaterialApi::class)
    fun ModalBottomSheetSample(value: Boolean) {
        val sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden, skipHalfExpanded = true)
        val scope = rememberCoroutineScope()
        SideEffect {
            scope.launch {
                if (value) {
                    sheetState.show()
                }
            }
        }
        ModalBottomSheetContent(sheetState)
    }

    @OptIn(ExperimentalMaterialApi::class)
    @Composable
    fun ModalBottomSheetContent(sheetState: ModalBottomSheetState) {
        ModalBottomSheetLayout(
            sheetState = sheetState,
            sheetContent = {
                LazyColumn {
                    items(5) {
                        ListItem(
                            icon = {
                                Icon(
                                    Icons.Default.Favorite,
                                    contentDescription = null
                                )
                            },
                            text = { Text("项目 $it") },
                        )
                    }
                }
            }
        ) {}
    }

}

注意:我已经将代码中的HTML编码字符进行了适当的替换。如果需要进一步的帮助,请告诉我。

英文:

I changes two things.

  1. Change State of function i.e. StateFul and StateLess separate function.
  2. Change from LiveData to MutableSharedFlow and it working fine.

MainActivityViewModel.kt

class MainActivityViewModel : ViewModel() {
    val showBottomSheetContent by lazy { MutableSharedFlow&lt;Boolean&gt;() }
}

MainActivity.kt

class MainActivity : AppCompatActivity(), HideViewListener {

    private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
    private val viewModel by viewModels&lt;MainActivityViewModel&gt;()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.showBottomSheetContent
                    .collect { value -&gt;
                        binding.bottomSheetComposeView.setContent {
                            ModalBottomSheetSample(value)
                        }
                    }
            }
        }

        binding.buttonComposeView.setContent {
            ButtonViewContent()
        }
    }

    @Composable
    fun ButtonViewContent() {
        val scope = rememberCoroutineScope()
        Column(Modifier.fillMaxSize()) {
            Button(
                onClick = {
                    scope.launch {
                        viewModel.showBottomSheetContent.emit(true)
                    }
                }
            ) {
                Text(text = &quot;Open Bottom Sheet&quot;)
            }
        }
    }

    @Composable
    @OptIn(ExperimentalMaterialApi::class)
    fun ModalBottomSheetSample(value: Boolean) {
        val sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden, skipHalfExpanded = true)
        val scope = rememberCoroutineScope()
        SideEffect {
            scope.launch {
                if (value) {
                    sheetState.show()
                }
            }
        }
        ModalBottomSheetContent(sheetState)
    }

    @OptIn(ExperimentalMaterialApi::class)
    @Composable
    fun ModalBottomSheetContent(sheetState: ModalBottomSheetState) {
        ModalBottomSheetLayout(
            sheetState = sheetState,
            sheetContent = {
                LazyColumn {
                    items(5) {
                        ListItem(
                            icon = {
                                Icon(
                                    Icons.Default.Favorite,
                                    contentDescription = null
                                )
                            },
                            text = { Text(&quot;Item $it&quot;) },
                        )
                    }
                }
            }
        ) {}
    }

}

huangapple
  • 本文由 发表于 2023年4月13日 17:34:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76003907.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定