Reputation: 174
I'm using if-else state in jetpck compose project to compose UI. It working fine as it needed but the problem is that even if the first if statements are to be passed it shouls a flicker effect of that ui as well and then show the final ui that is supposed to be shown. For example we have AccessInfo()
and MediaScreen()
now in if statement these are to be composed in sequence wihtout any flickering or recompositon.
Here what i have tried
@Composable
fun PermissionHandler(
viewModel: HomeViewModel,
state: HomeUIState
) {
val context = LocalContext.current
val permissionsState = rememberMultiplePermissionsState(permissions)
var selectedUri: Uri?
val safLauncher =
rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) {
selectedUri = result.data?.data
if (selectedUri != null) {
if (selectedUri.toString() == "content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fmedia") {
viewModel.saveSAFValue(true)
context.contentResolver.takePersistableUriPermission(
selectedUri!!,
Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION
)
}
}
}
}
if (!permissionsState.allPermissionsGranted) {
AccessInfo(
accessModel = AccessModel(
lottieComposition = R.raw.gallery_permission,
title = R.string.permission_required,
description = R.string.permission_read_and_write,
buttonText = R.string.allow_access_button
),
onAllowButtonClick = { permissionsState.launchMultiplePermissionRequest() })
} else if (!state.isSAFGranted) {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
.apply {
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
}
AccessInfo(
accessModel = AccessModel(
lottieComposition = R.raw.gallery_permission,
title = R.string.folder_access_required,
description = R.string.folder_access_required_desc,
buttonText = R.string.allow_folder_access_button,
linkText = R.string.why_we_need_this,
popUpContent = R.array.SAF_requirement_details,
popUpButtonText = R.string.allow_folder_access_button
),
isPopupEnabled = true,
onAllowButtonClick = { safLauncher.launch(intent) })
} else {
MediaScreen()
}
}
Upvotes: 1
Views: 147
Reputation: 88072
Compose has movableContentOf for such use-case. If it's called once in different locations, same view will be reused - just make sure you're handling parameters change in AccessInfo
correctly.
val accessInfo = movableContentOf { isPopupEnabled: Boolean, onAllowButtonClick: () -> Unit ->
AccessInfo(
accessModel = /*...*/,
isPopupEnabled = isPopupEnabled,
onAllowButtonClick = onAllowButtonClick
)
}
if (!permissionsState.allPermissionsGranted) {
accessInfo(
false,
{ permissionsState.launchMultiplePermissionRequest() }
)
} else if (!state.isSAFGranted) {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
.apply {
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_PREFIX_URI_PERMISSION)
addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
}
accessInfo(
true,
{ safLauncher.launch(intent) }
)
}
Upvotes: 0