I am currently developing a customized PopupView to behave like ModalBottomSheetLayout but more manageable and advanced. I want to be able to access this PopupManager class from anywhere without passing it as a parameter to other functions so that the structure I will create is more robust and more manageable. Here is the code:
@HiltViewModel
class PopupManager @Inject constructor(
initialValue: PopupViewStateValue = PopupViewStateValue.Hidden
) : ViewModel() {
val popupViewState = mutableStateOf(initialValue)
}
class ActivityHelpCenterCompose : ComponentActivity() {
private val popUpManager: PopupManager by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Box {
HelpCenterPageView(
modifier = Modifier.zIndex(1f),
popupManager = popUpManager
)
PopupView(
popupManager = popUpManager,
modifier = Modifier.zIndex(2f)
) {
}
}
}
}
}
As it can be seen, I am sending popup manager as a parameter to the composable functions which are HelpCenterPageView and PopupView and that is exactly what I want to avoid.
This is the code for the HelpCenterPageView and I am opening my popupview in the extension function that I wrote which is popupManager.expand in the NavigationBarView clickable.
@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
@Composable
fun HelpCenterPageView(
popupManager: PopupManager,
modifier: Modifier?,
) {
Scaffold(
modifier = modifier ?: Modifier,
topBar = {
NavigationBarView(
title = stringResource(id = R.string.profile_page_help),
modifier = Modifier.clickable {
popupManager.expand()
}
)
}) {
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(top = 22.dp, start = 22.dp, end = 22.dp)
.background(
color = colorResource(
id = R.color.fz_background
)
)
) {
TextView(
text = stringResource(id = R.string.help_page_training_center),
font = Font.F17SB.textStyle,
color = colorResource(id = R.color.fz_dark_colour),
modifier = null
)
Column(modifier = Modifier.padding(top = 22.dp)) {
UpComingTrainingView(
training = Trainings(),
onShareClick = { },
onWatchClick = { },
modifier = null
)
Spacer(modifier = Modifier.padding(top = 22.dp))
HelpCenterSectionView(
sectionTitle = stringResource(id = R.string.online_zoom_training_page_next_trainings),
sectionImage = painterResource(id = R.drawable.online_educations_icon),
modifier = null
) {}
Spacer(modifier = Modifier.padding(top = 22.dp))
HelpCenterSectionView(
sectionTitle = stringResource(id = R.string.online_zoom_training_page_previous_trainings),
sectionImage = painterResource(id = R.drawable.education_records_history_property),
modifier = null
) {
}
}
}
Spacer(
modifier = Modifier
.padding(top = 22.dp)
.fillMaxWidth()
.height(10.dp)
.background(
color = colorResource(
id = R.color.fz_cool_gray02
)
)
)
Column(
modifier = Modifier
.fillMaxWidth()
.padding(top = 22.dp, start = 22.dp, end = 22.dp)
) {
TextView(
text = stringResource(id = R.string.profile_page_help),
font = Font.F17SB.textStyle,
color = colorResource(id = R.color.fz_dark_colour),
modifier = null
)
Spacer(modifier = Modifier.padding(top = 22.dp))
HelpCenterSectionView(
sectionTitle = stringResource(id = R.string.help_page_live_desk),
sectionImage = painterResource(id = R.drawable.settings_whatsapp_icon),
modifier = null
) {
}
Spacer(modifier = Modifier.padding(top = 22.dp))
HelpCenterSectionView(
sectionTitle = stringResource(id = R.string.help_page_feature),
sectionImage = painterResource(id = R.drawable.request_suggestion_icon),
modifier = null
) {
}
Spacer(modifier = Modifier.padding(top = 22.dp))
HelpCenterSectionView(
sectionTitle = stringResource(id = R.string.help_page_bug),
sectionImage = painterResource(id = R.drawable.bug_report_icon),
modifier = null
) {
}
Spacer(modifier = Modifier.padding(top = 22.dp))
HelpCenterSectionView(
sectionTitle = stringResource(id = R.string.help_page_call_center),
sectionImage = painterResource(id = R.drawable.settings_call_property),
modifier = null
) {
}
}
Column(
modifier = Modifier
.padding(
top = 42.dp,
bottom = 42.dp,
start = 22.dp,
end = 22.dp
)
.fillMaxWidth(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
TextView(
text = "${R.string.help_page_version.localized()} ${BuildConfig.VERSION_NAME} ( ${BuildConfig.VERSION_CODE} )",
font = Font.F15SB.textStyle,
color = colorResource(id = R.color.fz_dark_colour),
modifier = null
)
}
}
}
}
Also, there are cases that I will need to open different popups in the same page for example 5 different popups. Do I have to assign different variables for each of the popups or is there a more generic way to handle this ?
CodePudding user response:
You can pass a Unit as a parameter.
@Composable
fun HelpCenterPageView(
modifier: Modifier = Modifier,
onClick: () -> Unit,
)
and
modifier = Modifier.clickable {
onClick()
}
and then
HelpCenterPageView(
modifier = Modifier.zIndex(1f),
){
popupManager.expand()
}
CodePudding user response:
You can use CompositionLocalProvider for this. This is a generic example.
Create Composition local with type of viewmodel.This will be holding viewmodel instance
val MyCompositionLocal = staticCompositionLocalOf<MyViewModel> { error("No Viewmodel provided") }
In fragment /activity, you should wrap composable view with
CompositionLocalProvider
and provide the viewmodel instance to the view tree.class MyFragment : Fragment() { private val viewModel by viewModels<MyViewModel>() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { setContent { CompositionLocalProvider(MyCompositionLocal provides viewModel) { MyComposeScreen() } } } } }
In any composables in activity/fragment tree, you get viewmodel instance using
CompositionLocal.current
@Composable fun MyComposeScreen() { val viewmodel = MyCompositionLocal.current //This will give viewmodel instance. }