Составление представления без перекомпоновки при изменении состояния ⇐ Android
-
Anonymous
Составление представления без перекомпоновки при изменении состояния
Искал Neo Launcher Feeder на github.
Обнаружена проблема, из-за которой представление составления в ComposeOverlayView не перекомпоновывается, несмотря на изменения состояния. Я изменил setContent в onCreate специально для решения этой проблемы и явно добавил в класс интерфейс LifecycleOwner.
В целом реализованы все интерфейсы, которые должны перекомпоновать составные элементы LifecycleOwner, SavedStateRegistryOwner, ViewModelStoreOwner
Попробовал различные решения, включая Jetpack Compose, рекомпозиция не срабатывает при использовании пользовательского владельца Lifecycle/ViewModelStore/SavedStateRegistry Owner
/* * Этот файл является частью Neo Feed. * Авторские права (c) принадлежат Саулу Энрикесу, 2023 г. * * Эта программа является бесплатным программным обеспечением: вы можете распространять ее и/или изменять. * это согласно условиям Стандартной общественной лицензии GNU, как * опубликовано Фондом свободного программного обеспечения, либо версия 3 * Лицензия, или (по вашему выбору) любая более поздняя версия. * * Данная программа распространяется в надежде, что она будет полезна, * но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ; даже без подразумеваемой гарантии * ТОВАРНАЯ ПРИГОДНОСТЬ или ПРИГОДНОСТЬ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ. См. * Стандартная общественная лицензия GNU для более подробной информации. * * Вы должны были получить копию Стандартной общественной лицензии GNU. * вместе с этой программой. Если нет, см. . */ пакет com.saulhdev.feeder.overlay импортировать android.content.Context импортировать android.os.Bundle импортировать android.view.View импортировать androidx.activity.OnBackPressedDispatcher импортировать androidx.activity.OnBackPressedDispatcherOwner импортировать androidx.activity.result.ActivityResultRegistry импортировать androidx.activity.result.ActivityResultRegistryOwner импортировать androidx.activity.setViewTreeOnBackPressedDispatcherOwner импортировать androidx.appcompat.view.ContextThemeWrapper импортировать androidx.compose.runtime.getValue импортировать androidx.compose.runtime.mutableStateOf импортировать androidx.compose.runtime.remember импортировать androidx.compose.runtime.setValue импортировать androidx.compose.ui.platform.ComposeView импортировать androidx.lifecycle.Lifecycle импортировать androidx.lifecycle.LifecycleOwner импортировать androidx.lifecycle.LifecycleRegistry импортировать androidx.lifecycle.ViewModelStore импортировать androidx.lifecycle.ViewModelStoreOwner импортировать androidx.lifecycle.setViewTreeLifecycleOwner импортировать androidx.lifecycle.setViewTreeViewModelStoreOwner импортировать androidx.navigation.NavHostController импортировать androidx.navigation.compose.rememberNavController импортировать androidx.savedstate.SavedStateRegistry импортировать androidx.savedstate.SavedStateRegistryController импортировать androidx.savedstate.SavedStateRegistryOwner импортировать androidx.savedstate.setViewTreeSavedStateRegistryOwner импортировать com.google.android.libraries.gsa.d.a.OverlayController импортировать com.saulhdev.feeder.NFApplication импортировать com.saulhdev.feeder.R импортировать com.saulhdev.feeder.compose.pages.OverlayPage импортировать com.saulhdev.feeder.theme.AppTheme импортировать org.kodein.di.DI импортировать org.kodein.di.DIAware импортировать org.kodein.di.android.closestDI импортировать org.kodein.di.compose.withDI класс ComposeOverlayView(val context: Context): OverlayController(context, R.style.AppTheme, R.style.WindowTheme), LifecycleOwner, SavedStateRegistryOwner, ViewModelStoreOwner, OnBackPressedDispatcherOwner, ActivityResultRegistryOwner, DIAware { частный lateinit var rootView: Посмотреть частный lateinit var composeView: ComposeView частный lateinit var navController: NavHostController частный val lifecycleRegistry = LifecycleRegistry(this) переопределить жизненный цикл val: Lifecycle get() = lifecycleRegistry переопределить значение onBackPressedDispatcher: OnBackPressedDispatcher get() = OnBackPressedDispatcher() частный val savedStateRegistryController = SavedStateRegistryController.create(this) переопределить значение savedStateRegistry: SavedStateRegistry get() = saveStateRegistryController.savedStateRegistry частный val родительскийDI: DI по ближайшемуDI() переопределить val di: DI с помощью DI.lazy {extend(parentDI) } в этом { saveStateRegistryController.performAttach() saveStateRegistryController.performRestore (ноль) lifecycleRegistry.currentState = Lifecycle.State.STARTED } переопределить fun onCreate(bundle: Bundle?) { super.onCreate(пакет) rootView = View.inflate( ContextThemeWrapper(это, R.style.AppTheme), R.layout.compose_overlay, контейнер ) lifecycleRegistry.currentState = Lifecycle.State.CREATED rootView.setViewTreeSavedStateRegistryOwner(это) rootView.setViewTreeLifecycleOwner(это) rootView.setViewTreeViewModelStoreOwner(это) rootView.setViewTreeOnBackPressedDispatcherOwner(это) composeView = rootView.findViewById(R.id.compose_view) composeView.setContent { navController = запомнитьNavController() Тема приложения { вар т, запомнив { mutableStateOf (ложь) } androidx.compose.material3.Surface { androidx.compose.material3.Button(onClick = { т = !т }) { androidx.compose.material3.Text(text = "Начало: $t") } } } } } переопределить удовольствие onDestroy() { супер.onDestroy() lifecycleRegistry.currentState = Lifecycle.State.DESTROYED } переопределить удовольствие onResume() { супер.onResume() lifecycleRegistry.currentState = Lifecycle.State.RESUMED } переопределить значение viewModelStore: ViewModelStore получить() = МагазинВидМоделей() переопределить значение ActivityResultRegistry: ActivityResultRegistry get() = NFApplication.mainActivity!!.activityResultRegistry } Ссылки на похожие проблемы
как использовать Jetpack Compose в сервисе (плавающее окно)
InputMethodService с Jetpack Compose — ComposeView вызывает: Компоновка в представление, которое не распространяет ViewTreeLifecycleOwner
ИЗМЕНИТЬ 01.09.24 Вокруг добавлен наблюдатель жизненного цикла в композицию setContent и, как ожидалось, он не вызывался
DisposableEffect(lifecycleOwner) { val наблюдатель = объект: Жизненный циклОбсервер { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) весело onResume() { Log.v(TAG,"onResume Compose") } } lifecycleOwner.lifecycle.addObserver(наблюдатель) onDispose { lifecycleOwner.lifecycle.removeObserver(наблюдатель) } }
Искал Neo Launcher Feeder на github.
Обнаружена проблема, из-за которой представление составления в ComposeOverlayView не перекомпоновывается, несмотря на изменения состояния. Я изменил setContent в onCreate специально для решения этой проблемы и явно добавил в класс интерфейс LifecycleOwner.
В целом реализованы все интерфейсы, которые должны перекомпоновать составные элементы LifecycleOwner, SavedStateRegistryOwner, ViewModelStoreOwner
Попробовал различные решения, включая Jetpack Compose, рекомпозиция не срабатывает при использовании пользовательского владельца Lifecycle/ViewModelStore/SavedStateRegistry Owner
/* * Этот файл является частью Neo Feed. * Авторские права (c) принадлежат Саулу Энрикесу, 2023 г. * * Эта программа является бесплатным программным обеспечением: вы можете распространять ее и/или изменять. * это согласно условиям Стандартной общественной лицензии GNU, как * опубликовано Фондом свободного программного обеспечения, либо версия 3 * Лицензия, или (по вашему выбору) любая более поздняя версия. * * Данная программа распространяется в надежде, что она будет полезна, * но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ; даже без подразумеваемой гарантии * ТОВАРНАЯ ПРИГОДНОСТЬ или ПРИГОДНОСТЬ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ. См. * Стандартная общественная лицензия GNU для более подробной информации. * * Вы должны были получить копию Стандартной общественной лицензии GNU. * вместе с этой программой. Если нет, см. . */ пакет com.saulhdev.feeder.overlay импортировать android.content.Context импортировать android.os.Bundle импортировать android.view.View импортировать androidx.activity.OnBackPressedDispatcher импортировать androidx.activity.OnBackPressedDispatcherOwner импортировать androidx.activity.result.ActivityResultRegistry импортировать androidx.activity.result.ActivityResultRegistryOwner импортировать androidx.activity.setViewTreeOnBackPressedDispatcherOwner импортировать androidx.appcompat.view.ContextThemeWrapper импортировать androidx.compose.runtime.getValue импортировать androidx.compose.runtime.mutableStateOf импортировать androidx.compose.runtime.remember импортировать androidx.compose.runtime.setValue импортировать androidx.compose.ui.platform.ComposeView импортировать androidx.lifecycle.Lifecycle импортировать androidx.lifecycle.LifecycleOwner импортировать androidx.lifecycle.LifecycleRegistry импортировать androidx.lifecycle.ViewModelStore импортировать androidx.lifecycle.ViewModelStoreOwner импортировать androidx.lifecycle.setViewTreeLifecycleOwner импортировать androidx.lifecycle.setViewTreeViewModelStoreOwner импортировать androidx.navigation.NavHostController импортировать androidx.navigation.compose.rememberNavController импортировать androidx.savedstate.SavedStateRegistry импортировать androidx.savedstate.SavedStateRegistryController импортировать androidx.savedstate.SavedStateRegistryOwner импортировать androidx.savedstate.setViewTreeSavedStateRegistryOwner импортировать com.google.android.libraries.gsa.d.a.OverlayController импортировать com.saulhdev.feeder.NFApplication импортировать com.saulhdev.feeder.R импортировать com.saulhdev.feeder.compose.pages.OverlayPage импортировать com.saulhdev.feeder.theme.AppTheme импортировать org.kodein.di.DI импортировать org.kodein.di.DIAware импортировать org.kodein.di.android.closestDI импортировать org.kodein.di.compose.withDI класс ComposeOverlayView(val context: Context): OverlayController(context, R.style.AppTheme, R.style.WindowTheme), LifecycleOwner, SavedStateRegistryOwner, ViewModelStoreOwner, OnBackPressedDispatcherOwner, ActivityResultRegistryOwner, DIAware { частный lateinit var rootView: Посмотреть частный lateinit var composeView: ComposeView частный lateinit var navController: NavHostController частный val lifecycleRegistry = LifecycleRegistry(this) переопределить жизненный цикл val: Lifecycle get() = lifecycleRegistry переопределить значение onBackPressedDispatcher: OnBackPressedDispatcher get() = OnBackPressedDispatcher() частный val savedStateRegistryController = SavedStateRegistryController.create(this) переопределить значение savedStateRegistry: SavedStateRegistry get() = saveStateRegistryController.savedStateRegistry частный val родительскийDI: DI по ближайшемуDI() переопределить val di: DI с помощью DI.lazy {extend(parentDI) } в этом { saveStateRegistryController.performAttach() saveStateRegistryController.performRestore (ноль) lifecycleRegistry.currentState = Lifecycle.State.STARTED } переопределить fun onCreate(bundle: Bundle?) { super.onCreate(пакет) rootView = View.inflate( ContextThemeWrapper(это, R.style.AppTheme), R.layout.compose_overlay, контейнер ) lifecycleRegistry.currentState = Lifecycle.State.CREATED rootView.setViewTreeSavedStateRegistryOwner(это) rootView.setViewTreeLifecycleOwner(это) rootView.setViewTreeViewModelStoreOwner(это) rootView.setViewTreeOnBackPressedDispatcherOwner(это) composeView = rootView.findViewById(R.id.compose_view) composeView.setContent { navController = запомнитьNavController() Тема приложения { вар т, запомнив { mutableStateOf (ложь) } androidx.compose.material3.Surface { androidx.compose.material3.Button(onClick = { т = !т }) { androidx.compose.material3.Text(text = "Начало: $t") } } } } } переопределить удовольствие onDestroy() { супер.onDestroy() lifecycleRegistry.currentState = Lifecycle.State.DESTROYED } переопределить удовольствие onResume() { супер.onResume() lifecycleRegistry.currentState = Lifecycle.State.RESUMED } переопределить значение viewModelStore: ViewModelStore получить() = МагазинВидМоделей() переопределить значение ActivityResultRegistry: ActivityResultRegistry get() = NFApplication.mainActivity!!.activityResultRegistry } Ссылки на похожие проблемы
как использовать Jetpack Compose в сервисе (плавающее окно)
InputMethodService с Jetpack Compose — ComposeView вызывает: Компоновка в представление, которое не распространяет ViewTreeLifecycleOwner
ИЗМЕНИТЬ 01.09.24 Вокруг добавлен наблюдатель жизненного цикла в композицию setContent и, как ожидалось, он не вызывался
DisposableEffect(lifecycleOwner) { val наблюдатель = объект: Жизненный циклОбсервер { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) весело onResume() { Log.v(TAG,"onResume Compose") } } lifecycleOwner.lifecycle.addObserver(наблюдатель) onDispose { lifecycleOwner.lifecycle.removeObserver(наблюдатель) } }
Мобильная версия