From a901a5e72b4c44c5e2161e65f5c2e8a1168bab9a Mon Sep 17 00:00:00 2001 From: Aleksey Ivanovsky Date: Thu, 8 Feb 2024 20:20:41 +0100 Subject: [PATCH] Fix lifecycle propagation for ViewModelsAdapter --- .../core/binding/BindingAdapters.kt | 25 ------------------- .../core/extensions/RecyclerViewExt.kt | 11 ++++++++ .../diffViewer/DiffViewerFragment.kt | 23 +++++++++++++++-- .../filepicker/FilePickerFragment.kt | 21 ++++++++++++++-- .../presentation/main/MainActivity.kt | 10 ++++++++ .../presentation/note/NoteFragment.kt | 17 ++++++++++--- .../noteEditor/NoteEditorFragment.kt | 17 ++++++++++--- .../storagelist/StorageListFragment.kt | 23 ++++++++++++++--- .../presentation/unlock/UnlockFragment.kt | 15 +++++++++++ .../core_base_activity_with_side_menu.xml | 4 +-- .../main/res/layout/diff_viewer_fragment.xml | 2 -- .../main/res/layout/file_picker_fragment.xml | 4 +-- .../main/res/layout/note_editor_fragment.xml | 4 +-- app/src/main/res/layout/note_fragment.xml | 4 +-- .../main/res/layout/storage_list_fragment.xml | 4 +-- app/src/main/res/layout/unlock_fragment.xml | 3 +-- 16 files changed, 130 insertions(+), 57 deletions(-) create mode 100644 app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/extensions/RecyclerViewExt.kt diff --git a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/binding/BindingAdapters.kt b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/binding/BindingAdapters.kt index bde7f86a..53f0384e 100644 --- a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/binding/BindingAdapters.kt +++ b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/binding/BindingAdapters.kt @@ -22,7 +22,6 @@ import androidx.core.graphics.drawable.DrawableCompat import androidx.core.view.isVisible import androidx.databinding.BindingAdapter import androidx.lifecycle.LiveData -import androidx.recyclerview.widget.RecyclerView import com.google.android.material.shape.CornerFamily import com.google.android.material.shape.MaterialShapeDrawable import com.google.android.material.shape.ShapeAppearanceModel @@ -35,7 +34,6 @@ import com.ivanovsky.passnotes.presentation.core.ScreenState import com.ivanovsky.passnotes.presentation.core.ScreenStateHandler import com.ivanovsky.passnotes.presentation.core.ViewModelTypes import com.ivanovsky.passnotes.presentation.core.adapter.StringArraySpinnerAdapter -import com.ivanovsky.passnotes.presentation.core.adapter.ViewModelsAdapter import com.ivanovsky.passnotes.presentation.core.widget.CellLinearLayout import com.ivanovsky.passnotes.presentation.core.widget.ErrorPanelView import com.ivanovsky.passnotes.presentation.core.widget.SecureTextView @@ -52,7 +50,6 @@ import com.ivanovsky.passnotes.presentation.core.widget.entity.TextInputType import com.ivanovsky.passnotes.presentation.core.widget.entity.TextTransformationMethod import com.ivanovsky.passnotes.presentation.core.widget.entity.TextTransformationMethod.PASSWORD import com.ivanovsky.passnotes.presentation.core.widget.entity.TextTransformationMethod.PLANE_TEXT -import com.ivanovsky.passnotes.util.getLifecycleOwner @BindingAdapter("screenState", "screenStateHandler") fun setScreenState( @@ -65,28 +62,6 @@ fun setScreenState( screenStateHandler.applyScreenState(view, screenState) } -@BindingAdapter("viewModels", "viewTypes") -fun setViewModel( - recyclerView: RecyclerView, - viewModelsData: List?, - viewTypes: ViewModelTypes -) { - val lifecycleOwner = recyclerView.context.getLifecycleOwner() - ?: throw IllegalStateException("context doesn't have LifecycleOwner") - - val adapter = (recyclerView.adapter as? ViewModelsAdapter) - ?: ViewModelsAdapter( - lifecycleOwner, - viewTypes - ).also { - recyclerView.adapter = it - } - - viewModelsData?.let { viewModels -> - adapter.updateItems(viewModels) - } -} - @BindingAdapter("viewModels", "viewTypes") fun setViewModels( view: CellLinearLayout, diff --git a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/extensions/RecyclerViewExt.kt b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/extensions/RecyclerViewExt.kt new file mode 100644 index 00000000..2d191ac1 --- /dev/null +++ b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/extensions/RecyclerViewExt.kt @@ -0,0 +1,11 @@ +package com.ivanovsky.passnotes.presentation.core.extensions + +import androidx.recyclerview.widget.RecyclerView +import com.ivanovsky.passnotes.presentation.core.BaseCellViewModel +import com.ivanovsky.passnotes.presentation.core.adapter.ViewModelsAdapter + +fun RecyclerView.setViewModels( + viewModels: List +) { + (adapter as ViewModelsAdapter).updateItems(viewModels) +} \ No newline at end of file diff --git a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/diffViewer/DiffViewerFragment.kt b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/diffViewer/DiffViewerFragment.kt index 27fb37ff..2c0b20be 100644 --- a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/diffViewer/DiffViewerFragment.kt +++ b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/diffViewer/DiffViewerFragment.kt @@ -10,7 +10,9 @@ import androidx.lifecycle.ViewModelProvider import com.ivanovsky.passnotes.R import com.ivanovsky.passnotes.databinding.DiffViewerFragmentBinding import com.ivanovsky.passnotes.presentation.core.DatabaseInteractionWatcher +import com.ivanovsky.passnotes.presentation.core.adapter.ViewModelsAdapter import com.ivanovsky.passnotes.presentation.core.extensions.getMandatoryArgument +import com.ivanovsky.passnotes.presentation.core.extensions.setViewModels import com.ivanovsky.passnotes.presentation.core.extensions.setupActionBar import com.ivanovsky.passnotes.presentation.core.extensions.withArguments @@ -29,18 +31,27 @@ class DiffViewerFragment : Fragment() { )[DiffViewerViewModel::class.java] } + private lateinit var binding: DiffViewerFragmentBinding + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { - val binding = DiffViewerFragmentBinding.inflate(inflater, container, false) + binding = DiffViewerFragmentBinding.inflate(inflater, container, false) .also { it.lifecycleOwner = viewLifecycleOwner it.viewModel = viewModel } - binding.recyclerView.itemAnimator = null + binding.recyclerView + .apply { + adapter = ViewModelsAdapter( + lifecycleOwner = viewLifecycleOwner, + viewTypes = viewModel.viewTypes + ) + itemAnimator = null + } return binding.root } @@ -57,6 +68,8 @@ class DiffViewerFragment : Fragment() { setHomeAsUpIndicator(null) } + subscribeToLiveData() + viewModel.start() } @@ -66,6 +79,12 @@ class DiffViewerFragment : Fragment() { return true } + private fun subscribeToLiveData() { + viewModel.cellViewModels.observe(viewLifecycleOwner) { viewModels -> + binding.recyclerView.setViewModels(viewModels) + } + } + companion object { private const val ARGUMENTS = "arguments" diff --git a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/filepicker/FilePickerFragment.kt b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/filepicker/FilePickerFragment.kt index 65ce04b3..0d6fb932 100644 --- a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/filepicker/FilePickerFragment.kt +++ b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/filepicker/FilePickerFragment.kt @@ -13,9 +13,11 @@ import com.ivanovsky.passnotes.domain.PermissionHelper import com.ivanovsky.passnotes.domain.entity.SystemPermission import com.ivanovsky.passnotes.injection.GlobalInjector.inject import com.ivanovsky.passnotes.presentation.core.FragmentWithDoneButton +import com.ivanovsky.passnotes.presentation.core.adapter.ViewModelsAdapter import com.ivanovsky.passnotes.presentation.core.dialog.AllFilesPermissionDialog import com.ivanovsky.passnotes.presentation.core.extensions.getMandatoryArgument import com.ivanovsky.passnotes.presentation.core.extensions.requestSystemPermission +import com.ivanovsky.passnotes.presentation.core.extensions.setViewModels import com.ivanovsky.passnotes.presentation.core.extensions.setupActionBar import com.ivanovsky.passnotes.presentation.core.extensions.showSnackbarMessage import com.ivanovsky.passnotes.presentation.core.extensions.withArguments @@ -39,6 +41,7 @@ class FilePickerFragment : } private val permissionHelper: PermissionHelper by inject() private val args by lazy { getMandatoryArgument(ARGUMENTS) } + private lateinit var binding: FilePickerFragmentBinding override fun onPermissionRequestResult(permission: SystemPermission, isGranted: Boolean) { when (permission) { @@ -79,12 +82,18 @@ class FilePickerFragment : container: ViewGroup?, savedInstanceState: Bundle? ): View { - return FilePickerFragmentBinding.inflate(inflater) + binding = FilePickerFragmentBinding.inflate(inflater) .also { it.lifecycleOwner = viewLifecycleOwner it.viewModel = viewModel } - .root + + binding.recyclerView.adapter = ViewModelsAdapter( + lifecycleOwner = viewLifecycleOwner, + viewTypes = viewModel.viewTypes + ) + + return binding.root } override fun onDoneMenuClicked() { @@ -111,9 +120,17 @@ class FilePickerFragment : override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + subscribeToLiveData() subscribeToEvents() } + private fun subscribeToLiveData() { + viewModel.cellViewModels.observe(viewLifecycleOwner) { viewModels -> + binding.recyclerView.setViewModels(viewModels) + } + } + private fun subscribeToEvents() { viewModel.isDoneButtonVisible.observe(viewLifecycleOwner) { isVisible -> setDoneButtonVisibility(isVisible) diff --git a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/main/MainActivity.kt b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/main/MainActivity.kt index 96778d4c..7230e5fa 100644 --- a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/main/MainActivity.kt +++ b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/main/MainActivity.kt @@ -23,8 +23,10 @@ import com.ivanovsky.passnotes.presentation.ApplicationLaunchMode import com.ivanovsky.passnotes.presentation.autofill.model.AutofillStructure import com.ivanovsky.passnotes.presentation.core.BaseFragment import com.ivanovsky.passnotes.presentation.core.ThemeProvider +import com.ivanovsky.passnotes.presentation.core.adapter.ViewModelsAdapter import com.ivanovsky.passnotes.presentation.core.extensions.getMandatoryExtra import com.ivanovsky.passnotes.presentation.core.extensions.initActionBar +import com.ivanovsky.passnotes.presentation.core.extensions.setViewModels import com.ivanovsky.passnotes.presentation.core.permission.PermissionRequestResultReceiver import com.ivanovsky.passnotes.presentation.core.permission.PermissionRequestSender import com.ivanovsky.passnotes.presentation.main.ActivityResultManager.LauncherType @@ -94,6 +96,11 @@ class MainActivity : it.navigationViewModel = navigationViewModel } + binding.navigationRecyclerView.adapter = ViewModelsAdapter( + lifecycleOwner = this, + viewTypes = navigationViewModel.cellViewTypes + ) + setContentView(binding.root) initActionBar(R.id.toolbar) @@ -170,6 +177,9 @@ class MainActivity : } private fun subscribeToLiveData() { + navigationViewModel.cellViewModels.observe(this) { viewModels -> + binding.navigationRecyclerView.setViewModels(viewModels) + } navigationViewModel.isNavigationMenuEnabled.observe(this) { setDrawerEnabled(it) } diff --git a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/note/NoteFragment.kt b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/note/NoteFragment.kt index ab0bb33e..52adf907 100644 --- a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/note/NoteFragment.kt +++ b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/note/NoteFragment.kt @@ -9,7 +9,6 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.observe import com.github.terrakok.cicerone.Router import com.ivanovsky.passnotes.R import com.ivanovsky.passnotes.data.entity.Note @@ -20,11 +19,13 @@ import com.ivanovsky.passnotes.presentation.Screens import com.ivanovsky.passnotes.presentation.autofill.AutofillDialogFactory import com.ivanovsky.passnotes.presentation.core.BaseFragment import com.ivanovsky.passnotes.presentation.core.DatabaseInteractionWatcher +import com.ivanovsky.passnotes.presentation.core.adapter.ViewModelsAdapter import com.ivanovsky.passnotes.presentation.core.dialog.ConfirmationDialog import com.ivanovsky.passnotes.presentation.core.extensions.finishActivity import com.ivanovsky.passnotes.presentation.core.extensions.getMandatoryArgument import com.ivanovsky.passnotes.presentation.core.extensions.openUrl import com.ivanovsky.passnotes.presentation.core.extensions.sendAutofillResult +import com.ivanovsky.passnotes.presentation.core.extensions.setViewModels import com.ivanovsky.passnotes.presentation.core.extensions.setupActionBar import com.ivanovsky.passnotes.presentation.core.extensions.showSnackbarMessage import com.ivanovsky.passnotes.presentation.core.extensions.updateMenuItemVisibility @@ -52,6 +53,7 @@ class NoteFragment : BaseFragment() { } private val router: Router by inject() private var menu: Menu? = null + private lateinit var binding: NoteFragmentBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -116,12 +118,18 @@ class NoteFragment : BaseFragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View { - return NoteFragmentBinding.inflate(inflater, container, false) + binding = NoteFragmentBinding.inflate(inflater, container, false) .also { it.lifecycleOwner = viewLifecycleOwner it.viewModel = viewModel } - .root + + binding.recyclerView.adapter = ViewModelsAdapter( + lifecycleOwner = viewLifecycleOwner, + viewTypes = viewModel.viewTypes + ) + + return binding.root } override fun onStart() { @@ -140,6 +148,9 @@ class NoteFragment : BaseFragment() { } private fun subscribeToLiveData() { + viewModel.cellViewModels.observe(viewLifecycleOwner) { viewModels -> + binding.recyclerView.setViewModels(viewModels) + } viewModel.visibleMenuItems.observe(viewLifecycleOwner) { visibleItems -> menu?.let { menu -> updateMenuItemVisibility( diff --git a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/noteEditor/NoteEditorFragment.kt b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/noteEditor/NoteEditorFragment.kt index 24f28384..41e9b7ba 100644 --- a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/noteEditor/NoteEditorFragment.kt +++ b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/noteEditor/NoteEditorFragment.kt @@ -7,7 +7,6 @@ import android.view.View import android.view.ViewGroup import androidx.activity.OnBackPressedCallback import androidx.activity.addCallback -import androidx.lifecycle.observe import com.github.terrakok.cicerone.Router import com.ivanovsky.passnotes.R import com.ivanovsky.passnotes.databinding.NoteEditorFragmentBinding @@ -16,10 +15,12 @@ import com.ivanovsky.passnotes.presentation.ApplicationLaunchMode import com.ivanovsky.passnotes.presentation.Screens import com.ivanovsky.passnotes.presentation.core.DatabaseInteractionWatcher import com.ivanovsky.passnotes.presentation.core.FragmentWithDoneButton +import com.ivanovsky.passnotes.presentation.core.adapter.ViewModelsAdapter import com.ivanovsky.passnotes.presentation.core.dialog.ConfirmationDialog import com.ivanovsky.passnotes.presentation.core.extensions.getMandatoryArgument import com.ivanovsky.passnotes.presentation.core.extensions.hideKeyboard import com.ivanovsky.passnotes.presentation.core.extensions.requireArgument +import com.ivanovsky.passnotes.presentation.core.extensions.setViewModels import com.ivanovsky.passnotes.presentation.core.extensions.setupActionBar import com.ivanovsky.passnotes.presentation.core.extensions.showToastMessage import com.ivanovsky.passnotes.presentation.core.extensions.withArguments @@ -39,18 +40,25 @@ class NoteEditorFragment : FragmentWithDoneButton() { ) private val router: Router by inject() private var backCallback: OnBackPressedCallback? = null + private lateinit var binding: NoteEditorFragmentBinding override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { - return NoteEditorFragmentBinding.inflate(inflater, container, false) + binding = NoteEditorFragmentBinding.inflate(inflater, container, false) .also { it.lifecycleOwner = viewLifecycleOwner it.viewModel = viewModel } - .root + + binding.recyclerView.adapter = ViewModelsAdapter( + lifecycleOwner = viewLifecycleOwner, + viewTypes = viewModel.viewTypes + ) + + return binding.root } override fun onDoneMenuClicked() { @@ -103,6 +111,9 @@ class NoteEditorFragment : FragmentWithDoneButton() { } private fun subscribeToLiveData() { + viewModel.cellViewModels.observe(viewLifecycleOwner) { viewModels -> + binding.recyclerView.setViewModels(viewModels) + } viewModel.isDoneButtonVisible.observe(viewLifecycleOwner) { isVisible -> setDoneButtonVisibility(isVisible) } diff --git a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/storagelist/StorageListFragment.kt b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/storagelist/StorageListFragment.kt index addb3b8e..dab8316f 100644 --- a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/storagelist/StorageListFragment.kt +++ b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/storagelist/StorageListFragment.kt @@ -8,7 +8,6 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.observe import com.ivanovsky.passnotes.R import com.ivanovsky.passnotes.data.entity.FSAuthority import com.ivanovsky.passnotes.data.repository.file.AuthType @@ -16,7 +15,9 @@ import com.ivanovsky.passnotes.data.repository.file.FileSystemResolver import com.ivanovsky.passnotes.databinding.StorageListFragmentBinding import com.ivanovsky.passnotes.injection.GlobalInjector.inject import com.ivanovsky.passnotes.presentation.core.BaseFragment +import com.ivanovsky.passnotes.presentation.core.adapter.ViewModelsAdapter import com.ivanovsky.passnotes.presentation.core.extensions.getMandatoryArgument +import com.ivanovsky.passnotes.presentation.core.extensions.setViewModels import com.ivanovsky.passnotes.presentation.core.extensions.setupActionBar import com.ivanovsky.passnotes.presentation.core.extensions.withArguments import com.ivanovsky.passnotes.util.FileUtils.DEFAULT_DB_NAME @@ -37,6 +38,8 @@ class StorageListFragment : BaseFragment() { .get(StorageListViewModel::class.java) } + private lateinit var binding: StorageListFragmentBinding + override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) setupActionBar { @@ -62,12 +65,18 @@ class StorageListFragment : BaseFragment() { container: ViewGroup?, savedInstanceState: Bundle? ): View { - return StorageListFragmentBinding.inflate(inflater) + binding = StorageListFragmentBinding.inflate(inflater) .also { it.lifecycleOwner = viewLifecycleOwner it.viewModel = viewModel } - .root + + binding.recyclerView.adapter = ViewModelsAdapter( + lifecycleOwner = viewLifecycleOwner, + viewTypes = viewModel.viewTypes + ) + + return binding.root } override fun onOptionsItemSelected(item: MenuItem): Boolean { @@ -76,6 +85,7 @@ class StorageListFragment : BaseFragment() { viewModel.navigateBack() true } + else -> super.onOptionsItemSelected(item) } } @@ -88,9 +98,16 @@ class StorageListFragment : BaseFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + subscribeToLiveData() subscribeToLiveEvents() } + private fun subscribeToLiveData() { + viewModel.cellViewModels.observe(viewLifecycleOwner) { viewModels -> + binding.recyclerView.setViewModels(viewModels) + } + } + private fun subscribeToLiveEvents() { viewModel.showAuthActivityEvent.observe(viewLifecycleOwner) { fsAuthority -> showAuthActivity(fsAuthority) diff --git a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/unlock/UnlockFragment.kt b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/unlock/UnlockFragment.kt index 9c7af8a3..33e588bf 100644 --- a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/unlock/UnlockFragment.kt +++ b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/unlock/UnlockFragment.kt @@ -12,11 +12,13 @@ import com.ivanovsky.passnotes.databinding.UnlockFragmentBinding import com.ivanovsky.passnotes.domain.biometric.BiometricAuthenticator import com.ivanovsky.passnotes.injection.GlobalInjector.inject import com.ivanovsky.passnotes.presentation.core.BaseFragment +import com.ivanovsky.passnotes.presentation.core.adapter.ViewModelsAdapter import com.ivanovsky.passnotes.presentation.core.dialog.resolveConflict.ResolveConflictDialog import com.ivanovsky.passnotes.presentation.core.dialog.resolveConflict.ResolveConflictDialogArgs import com.ivanovsky.passnotes.presentation.core.extensions.finishActivity import com.ivanovsky.passnotes.presentation.core.extensions.getMandatoryArgument import com.ivanovsky.passnotes.presentation.core.extensions.sendAutofillResult +import com.ivanovsky.passnotes.presentation.core.extensions.setViewModels import com.ivanovsky.passnotes.presentation.core.extensions.setupActionBar import com.ivanovsky.passnotes.presentation.core.extensions.showSnackbarMessage import com.ivanovsky.passnotes.presentation.core.extensions.withArguments @@ -56,6 +58,11 @@ class UnlockFragment : BaseFragment() { it.viewModel = viewModel } + binding.recyclerView.adapter = ViewModelsAdapter( + lifecycleOwner = viewLifecycleOwner, + viewTypes = viewModel.fileCellTypes + ) + return binding.root } @@ -67,6 +74,8 @@ class UnlockFragment : BaseFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + + subscribeToLiveData() subscribeToLiveEvents() viewModel.loadData( @@ -75,6 +84,12 @@ class UnlockFragment : BaseFragment() { ) } + private fun subscribeToLiveData() { + viewModel.fileCellViewModels.observe(viewLifecycleOwner) { viewModels -> + binding.recyclerView.setViewModels(viewModels) + } + } + private fun subscribeToLiveEvents() { viewModel.isKeyboardVisibleEvent.observe(viewLifecycleOwner) { isVisible -> if (isVisible) { diff --git a/app/src/main/res/layout/core_base_activity_with_side_menu.xml b/app/src/main/res/layout/core_base_activity_with_side_menu.xml index 7ccb2dd6..1253a4c9 100644 --- a/app/src/main/res/layout/core_base_activity_with_side_menu.xml +++ b/app/src/main/res/layout/core_base_activity_with_side_menu.xml @@ -66,9 +66,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" - app:viewModels="@{navigationViewModel.cellViewModels}" - app:viewTypes="@{navigationViewModel.cellViewTypes}" /> + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> diff --git a/app/src/main/res/layout/diff_viewer_fragment.xml b/app/src/main/res/layout/diff_viewer_fragment.xml index 11b9ab04..7ab3cfc7 100644 --- a/app/src/main/res/layout/diff_viewer_fragment.xml +++ b/app/src/main/res/layout/diff_viewer_fragment.xml @@ -123,8 +123,6 @@ app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toBottomOf="@id/compareButton" - app:viewModels="@{viewModel.cellViewModels}" - app:viewTypes="@{viewModel.viewTypes}" app:visible="@{!viewModel.isButtonsVisible}" /> diff --git a/app/src/main/res/layout/file_picker_fragment.xml b/app/src/main/res/layout/file_picker_fragment.xml index f0d88d9d..5b7be3a2 100644 --- a/app/src/main/res/layout/file_picker_fragment.xml +++ b/app/src/main/res/layout/file_picker_fragment.xml @@ -55,9 +55,7 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toBottomOf="@id/currentPath" app:screenState="@{viewModel.screenState}" - app:screenStateHandler="@{viewModel.screenStateHandler}" - app:viewModels="@{viewModel.cellViewModels}" - app:viewTypes="@{viewModel.viewTypes}" /> + app:screenStateHandler="@{viewModel.screenStateHandler}" /> diff --git a/app/src/main/res/layout/note_editor_fragment.xml b/app/src/main/res/layout/note_editor_fragment.xml index ae5c86d7..aba1d107 100644 --- a/app/src/main/res/layout/note_editor_fragment.xml +++ b/app/src/main/res/layout/note_editor_fragment.xml @@ -39,9 +39,7 @@ app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toBottomOf="@id/errorPanelView" app:screenState="@{viewModel.screenState}" - app:screenStateHandler="@{viewModel.screenStateHandler}" - app:viewModels="@{viewModel.cellViewModels}" - app:viewTypes="@{viewModel.viewTypes}" /> + app:screenStateHandler="@{viewModel.screenStateHandler}" /> + app:screenStateHandler="@{viewModel.screenStateHandler}" /> + app:screenStateHandler="@{viewModel.screenStateHandler}" /> diff --git a/app/src/main/res/layout/unlock_fragment.xml b/app/src/main/res/layout/unlock_fragment.xml index 56cf077c..049415f9 100644 --- a/app/src/main/res/layout/unlock_fragment.xml +++ b/app/src/main/res/layout/unlock_fragment.xml @@ -69,6 +69,7 @@ app:screenStateHandler="@{viewModel.screenStateHandler}" />