2017-09-01 28 views
2

Ich versuche, ohne Erfolg, ein Problem für Tage zu lösen. Ich möchte meine RecyclerView immer dann aktualisieren, wenn sich die Datensätze eines bestimmten Modells in der Datenbank (DB Room) ändern. Ich verwende ViewModel, um die Modelldaten zu verarbeiten, und die Liste der Datensätze wird in LiveData gespeichert.Laden RecyclerView nach Datenänderung mit Room, ViewModel und LiveData

Datenbank

@Database(entities = arrayOf(Additive::class), version = ElementDatabase.DB_VERSION, exportSchema = false) 
    abstract class ElementDatabase() : RoomDatabase() { 

     companion object { 
      const val DB_NAME : String = "element_db" 
      const val DB_VERSION : Int = 1 

      fun get(appContext : Context) : ElementDatabase { 
       return Room.databaseBuilder(appContext, ElementDatabase::class.java, DB_NAME).build() 
      } 
     } 

     abstract fun additivesModels() : AdditiveDao 

    } 

Modell

@Entity 
class Additive { 

    @PrimaryKey @ColumnInfo(name = "id") 
    var number : String = "" 
    var dangerousness : Int = 0 
    var description : String = "" 
    var names : String = "" 
    var notes : String = "" 
    var risks : String = "" 
    var advice : String = "" 
} 

Dao

@Dao 
interface AdditiveDao { 

    @Query("SELECT * FROM Additive") 
    fun getAllAdditives() : LiveData<List<Additive>> 

    @Query("SELECT * FROM Additive WHERE id = :arg0") 
    fun getAdditiveById(id : String) : Additive 

    @Query("DELETE FROM Additive") 
    fun deleteAll() 

    @Insert(onConflict = REPLACE) 
    fun insert(additive: Additive) 

    @Update 
    fun update(additive: Additive) 

    @Delete 
    fun delete(additive: Additive) 
} 

Ansichtsmodell

class AdditiveViewModel(application: Application) : AndroidViewModel(application) { 

    private var elementDatabase : ElementDatabase 
    private val additivesModels : LiveData<List<Additive>> 

    init { 
     this.elementDatabase = ElementDatabase.get(appContext = getApplication()) 
     this.additivesModels = this.elementDatabase.additivesModels().getAllAdditives() 
    } 

    fun getAdditivesList() : LiveData<List<Additive>> { 
     return this.additivesModels 
    } 

    fun deleteItem(additive : Additive) { 
     DeleteAsyncTask(this.elementDatabase).execute(additive) 
    } 

    private class DeleteAsyncTask internal constructor(private val db: ElementDatabase) : AsyncTask<Additive, Void, Void>() { 

     override fun doInBackground(vararg params: Additive): Void? { 
      db.additivesModels().delete(params[0]) 
      return null 
     } 

    } 
} 

Fragment

class AdditivesFragment : LifecycleFragment() { 

    private var viewModel : AdditiveViewModel? = null 
    private var adapter : AdditivesAdapter? = null 

    companion object { 
     fun newInstance() : AdditivesFragment { 
      val f = AdditivesFragment() 
      val args = Bundle() 

      f.arguments = args 
      return f 
     } 
    } 

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { 
     return inflater?.inflate(R.layout.fragment_additives, container, false) 
    } 

    override fun onActivityCreated(savedInstanceState: Bundle?) { 
     this.adapter = AdditivesAdapter(ArrayList<Additive>()) 
     this.additives_list.layoutManager = GridLayoutManager(this.context, 2, GridLayoutManager.VERTICAL, false) 
     this.additives_list.adapter = this.adapter 

     this.viewModel = ViewModelProviders.of(this).get(AdditiveViewModel::class.java) 

     this.viewModel?.getAdditivesList()?.observe(this, Observer<List<Additive>> { additivesList -> 
      if(additivesList != null) { 
       this.adapter?.addItems(additivesList) 
      } 
     }) 
     super.onActivityCreated(savedInstanceState) 
    } 
} 

Nun ist meine Frage, warum die Beobachter nur einmal (am Anfang des Fragments) genannt und dann nicht wieder genannt wird? Wie kann ich den Beobachter ständig auf die Änderungen in der Datenbank achten (Einfügen, Aktualisieren, Löschen), damit mein RecyclerView sofort aktualisiert werden kann? Vielen Dank für einen Vorschlag.

Antwort

Verwandte Themen