Это поток: Activity -> Fragment1 -> Fragment2 -> Fragment3
У меня есть этот Fragment3 с представлением переключателя -> При нажатии на этот переключатель я вызываю viewModel метод, который запрашивает необходимое разрешение для включения этого переключателя.
Проблема в том, что каждый раз, когда я запрашиваю разрешение и разрешаю или запрещаю, действие воссоздается, и Fragment3 умирает, снова показывая первый фрагмент (Fragment1)
Я пытался использовать onSaveInstance состояние, но мне не было ясно, как вернуть экземпляр фрагмента после запроса разрешения вместо воссоздания всего.
Есть идеи, как мне решить эту проблему?
Упражнение:
class Activity : DaggerActivity<DaggerComponent>() {
private val viewModel: ActivityViewModel by injectionViewModels {
activityComponent.activityViewModel
}
override fun onSafeCreate(savedInstanceState: Bundle?) {
super.onSafeCreate(savedInstanceState)
setContentView(R.layout.single_fragment_activity)
if (savedInstanceState != null) {
onRestoreInstanceState(savedInstanceState)
} else
observeViewModel()
}
override fun onSafeResume() {
super.onSafeResume()
viewModel.onCheckFeatureState()
}
private fun observeViewModel() {
observe(viewModel.areAllPermissionsGiven) { areGiven ->
if (areGiven) {
replaceFragment(SettingsFragment(), R.id.fragment_container, false)
} else {
replaceFragment(PermissionsFragment(), R.id.fragment_container, false)
}
}
}}
MyFragment:
class MyFragment : DaggerFragment<DaggerComponent>() {
private val viewModel: FragmentViewModel by injectionActivityViewModels {
activityComponent.fragmentViewModel
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initialize()
}
private fun initialize() {
viewModel.onViewCreated()
toolbar.setNavigationOnClickListener { activity?.onBackPressed() }
initViews()
initObservables()
}
private fun initViews() {
switch.onClick {
viewModel.onToggleMonitoringSecurityClick()
}
}
private fun initObservables() {
observe(viewModel.state) { state ->
switch.isChecked = state.isEnabled
switchText.isGone = state.hasPermission
}
}}
Код, который я использую для запроса разрешения и включения функции с использованием общих настроек:
class Option @AssistedInject constructor(
@Assisted private val permission: Permission,
@Assisted private val dataSource: DataSource,
private val permissionStatus: GetPermissionStatusUseCase,
private val permissionRequest: RequestPermissionUseCase) {
fun isEnabled() = dataSource.isEnabled && hasPermission
suspend fun enable() = withContext(Dispatchers.IO) {
val enable = hasPermission || (permissionRequest(permission) is Response.Success)
if (enable) {
dataSource.isEnabled = true
}
enable
}
fun disable() {
dataSource.isEnabled = false
}
suspend fun toggle() {
if (isEnabled()) {
disable()
} else {
enable()
}
}
val hasPermission
get() = permissionStatus.invoke(permission) == PermissionStatus.ENABLED
@AssistedInject.Factory
interface Factory {
fun create(permission: Permission, dataSource: DataSource): Option
}}
Я использую приведенный выше объектный код домена на useCase, который предоставляет viewModel возвращаемое значение наличия разрешения или нет.