簡體   English   中英

房間實時數據,數據綁定問題:數據更改時 UI 不更新

[英]Room livedata , databinding issue : UI doesn't update when data changes

我現在正在開發一個應用程序,我在其中使用 MVVM 模式進行 UI 和存儲庫交互。 換句話說,我通過存儲庫從我的 ROOM 數據庫查詢中接收帶有模型列表的實時數據對象,然后將其分配給 viewmodel 中的我的實時數據變量。 之后,應該通過數據綁定將此數據填充到我的 xml 布局回收器視圖中,但它僅在片段初始化后才會發生。 在其他情況下,回收站視圖無效

道代碼:

@Query("SELECT * FROM note WHERE content LIKE :query ORDER BY isStarred")
    fun searchAllNotes(query : String?) : Flow<List<Note>>

視圖模型代碼:

@HiltViewModel
class HomeViewModel @Inject constructor (
    private val noteRepository : NoteRepository
) : ViewModel() {


    private var _notesLiveData : LiveData<List<Note>> = noteRepository.getAllNotes().asLiveData()
    val notesLiveData  get()= _notesLiveData



    fun searchNotes(query : String){
        viewModelScope.launch(Dispatchers.IO){
            _notesLiveData = noteRepository.searchAllNotes(query).asLiveData()
        }
    }

    fun deleteNote(note : Note){
        viewModelScope.launch(Dispatchers.IO){
            noteRepository.deleteNote(note)
        }
    }

    fun updateNoteChecked(note : Note){
        viewModelScope.launch(Dispatchers.IO){
            noteRepository.updateNoteChecked(note.id, note.isStarred)
        }
    }

片段代碼

@AndroidEntryPoint
class HomeFragment : Fragment(),
NoteCardAdapter.NoteTouchListener,
SearchView.OnQueryTextListener{

    private var _binding : FragmentHomeBinding? = null
    val binding get() = _binding!!

    private val adapter by lazy {
        NoteCardAdapter(this as NoteCardAdapter.NoteTouchListener)
    }

    private val vm : HomeViewModel by viewModels()

    private val noteSharedViewModel : NoteSharedViewModel by activityViewModels()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentHomeBinding.inflate(inflater)
        return binding.root
    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

        binding.adapter = adapter
        binding.vm = vm

        binding.apply {
            lifecycleOwner = viewLifecycleOwner
            homeRecyclerView.isNestedScrollingEnabled = false
            homeRecyclerView.layoutManager = LinearLayoutManager(view.context)
            homeRecyclerView.itemAnimator= NotesItemAnimator()
        }
        binding.homeSearchView.isSubmitButtonEnabled  = true
        binding.homeSearchView.setOnQueryTextListener(this as SearchView.OnQueryTextListener)

        binding.addNoteButton.setOnClickListener{
            val note = Note(
                "","","",false, activity?.getDate(), folderId = -1
            )
            noteSharedViewModel.selectNote(note)
            val action = HomeFragmentDirections.actionHomeFragmentToSingleNoteFragment(
                isNew = true
            )

            findNavController().navigate(action)
        }

        binding.foldersButton.setOnClickListener{
            findNavController().navigate(HomeFragmentDirections.actionHomeFragmentToFoldersFragment())
        }
    }

xml布局代碼:

<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    >
    
    <data>
        <variable
            name="vm"
            type="com.example.leonidsnotesapplication.presentation.notes_feature.viewmodels.HomeViewModel" />

        <variable
            name="adapter"
            type="com.example.leonidsnotesapplication.presentation.notes_feature.adapters.NoteCardAdapter" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:background="@color/note_background_color_3"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".presentation.notes_feature.fragments.HomeFragment">

        <androidx.appcompat.widget.SearchView
            android:id="@+id/homeSearchView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:theme="@style/AppSearchView"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"/>

        <TextView
            android:id="@+id/tvRecentTitle"
            android:textStyle="bold"
            android:textSize="25sp"
            android:textColor="@color/button_color_2"
            android:text="@string/recent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:layout_marginStart="20dp"
            app:layout_constraintTop_toBottomOf="@id/homeSearchView"
            app:layout_constraintStart_toStartOf="parent"/>

        <ImageView
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:layout_marginStart="16dp"
            android:layout_marginTop="28dp"
            android:background="@drawable/ic_circle_arrow"
            app:layout_constraintStart_toEndOf="@id/tvRecentTitle"
            app:layout_constraintTop_toBottomOf="@id/homeSearchView" />

        <androidx.recyclerview.widget.RecyclerView
            tools:listitem="@layout/note_card_view"
            android:scrollbars="vertical"
            android:scrollbarStyle="outsideInset"
            android:id="@+id/homeRecyclerView"
            android:layout_width="match_parent"
            android:requiresFadingEdge="vertical"
            android:fadingEdge="vertical"
            android:fadingEdgeLength="15dp"
            android:layout_height="500dp"
            android:layout_marginTop="30dp"
            app:setNoteAdapter="@{adapter}"
            app:submitNoteList="@{vm.notesLiveData}"
            app:layout_constraintTop_toBottomOf="@id/tvRecentTitle"
            app:layout_constraintStart_toStartOf="parent"
            />

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:backgroundTint="@color/button_color_1"
            android:id="@+id/add_note_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:src="@drawable/ic_create"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent" />

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:backgroundTint="@color/button_color_1"
            android:id="@+id/folders_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:src="@drawable/ic_folders_stack"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent" />


    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

數據綁定適配器:

@BindingAdapter("submitNoteList")
fun submitNoteList(recyclerView: RecyclerView, data : List<Note>?){
    val adapter = recyclerView.adapter as NoteCardAdapter
    adapter.setData((data as ArrayList<Note>? ?: arrayListOf()))
}

@BindingAdapter("setNoteAdapter")
fun setNoteAdapter(recyclerView: RecyclerView, adapter: NoteCardAdapter){
    adapter.let {
        recyclerView.adapter = it
    }
}

您應該觀察您的實時數據。 示例代碼是: vm.notesLiveData.observe(viewLifecycleOwner) { adapter.submitList(it) }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM