RE
04/27/2022, 2:04 PMTolriq
04/27/2022, 3:15 PMnuhkoca
04/27/2022, 4:03 PMste
04/27/2022, 5:53 PM1.2.0-alpha08
and 1.2.0-alpha07
.Lilly
04/27/2022, 10:31 PMval scaffoldState = rememberScaffoldState()
val scope = rememberCoroutineScope()
LaunchedEffect(screenState.message) {
println("screen show message: ${screenState.message}.")
whenNotNull(screenState.message) { msg ->
scope.launch { scaffoldState.snackbarHostState.showSnackbar(msg) } // triggered twice
}
}
@Stable
class ScreenState {
var isLoading by mutableStateOf(false)
var message by mutableStateOf<String?>(null)
var isFullScreen by mutableStateOf(false)
}
// in viewmodel
companion object {
val screenState = ScreenState()
}
How can the snackbar be triggered twice when LaunchedEffect prevents that and screenState.message
does not change?
EDIT:
It only happens when I run the operation that updates screenState.message on screen start like:
DisposableEffect(Unit) {
viewModel.updateMessage()
onDispose { }
}
Calling the operation from a button doesn't trigger the snackbar twice?
EDIT2:
Solved: I took some time to note that LaunchedEffect
provides its own CoroutineScope
, shame on me.raghunandan
04/28/2022, 1:55 AMAbhilash
04/28/2022, 7:43 AMAbhilash
04/28/2022, 7:44 AMSatyam G
04/28/2022, 11:17 AMwintersoldier
04/29/2022, 7:23 AMMohan manu
04/29/2022, 9:09 AMmattinger
04/29/2022, 6:26 PMandrew
04/30/2022, 1:08 AMSterling Albury
04/30/2022, 4:21 PMShivam Dhuria
05/01/2022, 9:09 AMbohregard
05/01/2022, 8:58 PMMehdi Haghgoo
05/03/2022, 7:46 AMJustin
05/03/2022, 3:04 PM@Composable
fun CustomTheme(
content: @Composable () -> Unit
) {
MaterialTheme(
colors = LightColorPalette,
shapes = Shapes,
) {
CompositionLocalProvider(
LocalRippleTheme provides CustomRippleTheme,
LocalCustomTypography provides CustomTypography(),
content = content
)
}
}
object CustomTheme {
val typography: CustomTypography
@Composable
get() = LocalCustomTypography.current
}
rather than the convention seen in the docs:
@Composable
fun CustomTheme(
content: @Composable () -> Unit
) {
CompositionLocalProvider(
LocalRippleTheme provides CustomRippleTheme,
LocalCustomTypography provides CustomTypography(),
) {
MaterialTheme(
colors = LightColorPalette,
shapes = Shapes,
content = content
)
}
}
// ...
Are there any problems with using this style over the one in the docs?Yacov Rosenberg
05/03/2022, 11:02 PMSatyam G
05/04/2022, 2:32 PMDmitry Berdnikov
05/04/2022, 2:45 PMdata class State(val snackMessage: String? = null) // hoisted in ViewModel
//show snackbars inside root Composable
LaunchedEffect(state.snackMessage) {
if (state.snackMessage != null) {
snackbarHostState.showSnackbar(state.snackMessage)
viewModel.shackbarShown() // this make a copy of the state with snackMessage = null
}
}
So then I emit a new instance of state with snackMessage = null
, I expect that I see animation but instead it’s just gone.
I’ve made some experiment and removed the line viewModel.shackbarShown()
and then the exit animation was played…wintersoldier
05/05/2022, 6:46 AMColton Idle
05/06/2022, 11:57 AMChachako
05/06/2022, 1:25 PMmattinger
05/06/2022, 4:02 PModay
05/07/2022, 3:17 PMMarko Novakovic
05/07/2022, 4:52 PMclass UsersViewModel(
private val savedStateHandle: SavedStateHandle,
private val getUsers: () -> List<User>,
) : ViewModel() {
data class State(
val query: String,
val users: List<User>,
)
private var currentQuery by savedStateHandle.saveable(CurrentQuery) { mutableStateOf("") }
private val results by derivedStateOf {
getUsers().filter { currentQuery in it }
}
val state by derivedStateOf {
State(currentQuery, results)
}
fun queryUsers(query: String) {
savedStateHandle[CurrentQuery] = query
}
}
this doesn’t cause recomposition, why is that?
because not all `derivedStateOf`s are read from @Composable
function?Chachako
05/07/2022, 6:11 PMCompositionLocalProvider
? Can anyone post a link to a thread about this cheersGaurav Tyagi
05/08/2022, 6:33 PM@Composable
fun CastMiniController(modifier: Modifier = Modifier) {
AndroidViewBinding(factory = { inflater, parent, attachToParent ->
val binding = FragmentCastMiniControllerBinding.inflate(inflater, parent, false)
binding
}, modifier.fillMaxWidth().wrapContentHeight())
}
xml file
<?xml version="1.0" encoding="utf-8"?>
<androidx.fragment.app.FragmentContainerView xmlns:android="<http://schemas.android.com/apk/res/android>"
android:id="@+id/castMiniController"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:tag="miniControllerFragment"
android:name="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment">
</androidx.fragment.app.FragmentContainerView>
after adding it getting below crash
E/AndroidRuntime: FATAL EXCEPTION: main
android.view.InflateException: Binary XML file line #2 in layout/fragment_cast_mini_controller: Binary XML file line #2 in /cast_mini_controller: Views added to a FragmentContainerView must be associated with a Fragment. View android.widget.LinearLayout{6809a66 V.E...... ......I. 0,0-0,0 #7f0a0176 app:id/container_all} is not associated with a Fragment.
Caused by: android.view.InflateException: Binary XML file line #2 in /cast_mini_controller: Views added to a FragmentContainerView must be associated with a Fragment. View android.widget.LinearLayout{6809a66 V.E...... ......I. 0,0-0,0 #7f0a0176 app:id/container_all} is not associated with a Fragment.
Caused by: java.lang.IllegalStateException: Views added to a FragmentContainerView must be associated with a Fragment. View android.widget.LinearLayout{6809a66 V.E...... ......I. 0,0-0,0 #7f0a0176 app:id/container_all} is not associated with a Fragment.
at androidx.fragment.app.FragmentContainerView.addView(FragmentContainerView.kt:266)