我对MVVM体系结构还很陌生,但是为什么我似乎无法让Livedata对象更新为片段中的recyclerview,对此我有些困惑。在整个应用程序的各个地方使用“登录”,我发现sqlite表正在更新,只是不显示数据。
这是一个简单的笔记应用程序,目前我仅尝试显示sqlite表中的标题。我稍后会担心剩下的。
感谢您的帮助,我是房间的新手(通常是sqlite的用户,所以很多代码都是基于Room With a View教程的。
如果需要,我可以提供更多代码,我只是想让它尽可能地简单,以供他人查看!
TitlesFragment
import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView class TitlesFragment : Fragment(){ private lateinit var noteViewModel: NoteViewModel private lateinit var note: Note override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val rootView = inflater.inflate(R.layout.fragment_titles, container, false) val adapter = this.context?.let { NoteListAdapter(it) } noteViewModel = ViewModelProvider(this).get(NoteViewModel::class.java) noteViewModel.allNotes.observe(viewLifecycleOwner, Observer { notes -> notes?.let { adapter?.setNotes(it) } }) val recyclerView = rootView.findViewById< RecyclerView>(R.id.titlesrecyclerview) as RecyclerView recyclerView.layoutManager = LinearLayoutManager(activity) recyclerView.adapter = this.context?.let { NoteListAdapter(it) } return rootView } fun receiveNote(note: Note) { this.note = note noteViewModel.insert(this.note) } }
NoteListAdapter
import android.content.Context import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.TextView import androidx.lifecycle.LiveData import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.RecyclerView class NoteListAdapter internal constructor( context: Context ) : RecyclerView.Adapter<NoteListAdapter.NoteViewHolder>() { private val inflater: LayoutInflater = LayoutInflater.from(context) private var notes = emptyList<Note>() inner class NoteViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val noteItemView: TextView = itemView.findViewById(R.id.title_box) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NoteViewHolder { val itemView = inflater.inflate(R.layout.fragment_titles, parent, false) return NoteViewHolder(itemView) } override fun onBindViewHolder(holder: NoteViewHolder, position: Int) { val current = notes[position] holder.noteItemView.text = current.note } internal fun setNotes(notes: List<Note>) { this.notes = notes notifyDataSetChanged() } override fun getItemCount() = notes.size }
NoteViewModel
import android.app.Application import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.viewModelScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch class NoteViewModel (application: Application) : AndroidViewModel(application) { private val repository: NoteRepository val allNotes: LiveData<List<Note>> init { val notesDao = NoteDatabase.getDatabase(application, viewModelScope).noteDao() repository = NoteRepository(notesDao) allNotes = repository.allNotes } fun insert(note: Note) = viewModelScope.launch(Dispatchers.IO) { repository.insert(note) } }
NoteDatabase
import android.content.Context import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase import androidx.sqlite.db.SupportSQLiteDatabase import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @Database(entities = arrayOf(Note::class), version = 1, exportSchema = false) abstract class NoteDatabase : RoomDatabase() { abstract fun noteDao(): NoteDao companion object { @Volatile private var INSTANCE: NoteDatabase? = null fun getDatabase(context: Context, scope: CoroutineScope): NoteDatabase { val tempInstance = INSTANCE if (tempInstance != null) { return tempInstance } synchronized(this) { val instance = Room.databaseBuilder( context.applicationContext, NoteDatabase::class.java, "note_database" ).addCallback(NoteDatabaseCallback(scope)).build() INSTANCE = instance return instance } } } private class NoteDatabaseCallback( private val scope: CoroutineScope) : RoomDatabase.Callback() { override fun onOpen(db: SupportSQLiteDatabase) { super.onOpen(db) INSTANCE?.let { database -> scope.launch { populateDatabase(database.noteDao()) } } } suspend fun populateDatabase(noteDao: NoteDao) { noteDao.deleteAll() var note = Note("test1", "hello") noteDao.insert(note) note = Note("test2", "world") noteDao.insert(note) } } }
NoteRepository
import androidx.lifecycle.LiveData class NoteRepository(private val noteDao: NoteDao) { val allNotes: LiveData<List<Note>> = noteDao.getAllNotes() suspend fun insert(note: Note) { noteDao.insert(note) } }
NoteDao
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
@Dao
interface NoteDao {
@Query("SELECT * from note_table")
fun getAllNotes(): LiveData<List<Note>>
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(note: Note)
@Query("DELETE FROM note_table")
suspend fun deleteAll()
}
我对MVVM体系结构还很陌生,但是为什么我似乎无法让Livedata对象更新为片段中的recyclerview,对此我有些困惑。在整个...
查看onCreateView()
之后,您将拥有: