レルムを使用していて、素晴らしいです。RealmRecyclerViewAdapterにレルムクエリーの更新が反映されていません
何かに対処してください。私が何か悪いことをしているのかなと思います。
レルムクエリの結果を表示するために使用しているRealmRecyclerViewAdapter
があります。レルム内のレコードを追加または更新すると、これは完全に機能します。リサイクルビューでsetHasFixedSize(false)
にしていたので、すぐに更新することができました。これが正しいかどうかは分かりませんが、それはうまくいきます。
とにかく、それは私の問題ではありません。
私は自分のデータをフィルタリングすることを試みています。私は、次のクエリを持っている:
realm.where(Person::class.java).contains("name", nameFilter, Case.INSENSITIVE).findAllSorted("name")
私はリサイクル業者ビューにこのRealmResultsを渡すことだし、それは追加/更新に素晴らしい作品。
ただし、フィルタを試みると自動的に更新されません。
フィルタ(nameFilter
で指定)を単に変更するだけでは、クエリを再実行するには不十分です。これは私が推測するほど公平だ。私は文字列の値を変更したことを知るために領域がトリガーされないと思うので、
ただし、クエリを再計算しても、明示的にupdateData
をアダプタで呼び出さない限り、Recyclerビューで更新されないようです。これを行うには、これが最善の方法か、最も効率的な方法かどうかはわかりません。より良い方法がありますか?
完全なコード:
主な活動
class MainActivity : AppCompatActivity(), View.OnClickListener {
private val TAG: String = this::class.java.simpleName
private val realm: Realm = Realm.getInstance(RealmConfiguration.Builder().deleteRealmIfMigrationNeeded().build())
private var nameFilter = ""
private var allPersons: RealmResults<Person> = realm.where(Person::class.java).contains("name", nameFilter, Case.INSENSITIVE).findAllSorted("name")
private val adapter: PersonRecyclerViewAdapter = PersonRecyclerViewAdapter(allPersons)
private lateinit var disposable: Disposable
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
realm.executeTransaction({
// realm.deleteAll()
})
Log.i(TAG, "Deleted all objects from Realm")
buttonAddOrUpdatePerson.setOnClickListener(this)
setUpRecyclerView()
disposable = RxTextView.textChangeEvents(editTextNameFilter)
// .debounce(400, TimeUnit.MILLISECONDS) // default Scheduler is Computation
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith<DisposableObserver<TextViewTextChangeEvent>>(getSearchObserver())
}
private fun getSearchObserver(): DisposableObserver<TextViewTextChangeEvent> {
return object : DisposableObserver<TextViewTextChangeEvent>() {
override fun onComplete() {
Log.i(TAG,"--------- onComplete")
}
override fun onError(e: Throwable) {
Log.i(TAG, "--------- Woops on error!")
}
override fun onNext(onTextChangeEvent: TextViewTextChangeEvent) {
nameFilter = editTextNameFilter.text.toString()
allPersons = realm.where(Person::class.java).contains("name", nameFilter, Case.INSENSITIVE).findAllSorted("name")
// this is necessary or the recycler view doesn't update
adapter.updateData(allPersons)
Log.d(TAG, "Filter: $nameFilter")
}
}
}
override fun onDestroy() {
super.onDestroy()
realm.close()
}
override fun onClick(view: View?) {
if(view == null) return
when(view) {
buttonAddOrUpdatePerson -> handleAddOrUpdatePerson()
}
}
private fun handleAddOrUpdatePerson() {
val personToAdd = Person()
personToAdd.name = editTextName.text.toString()
personToAdd.email = editTextEmail.text.toString()
realm.executeTransactionAsync({
bgRealm -> bgRealm.copyToRealmOrUpdate(personToAdd)
})
}
private fun setUpRecyclerView() {
recyclerViewPersons.layoutManager = LinearLayoutManager(this)
recyclerViewPersons.adapter = adapter
recyclerViewPersons.setHasFixedSize(false)
recyclerViewPersons.addItemDecoration(DividerItemDecoration(this, LinearLayoutManager.VERTICAL))
}
}
PersonRecyclerViewAdapter
internal class PersonRecyclerViewAdapter(data: OrderedRealmCollection<Person>?, autoUpdate: Boolean = true) : RealmRecyclerViewAdapter<Person, PersonRecyclerViewAdapter.PersonViewHolder>(data, autoUpdate) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PersonViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.person_row, parent, false)
return PersonViewHolder(itemView)
}
override fun onBindViewHolder(holder: PersonViewHolder?, position: Int) {
if(holder == null || data == null) return
val personList = data ?: return
val person = personList[position]
holder.bind(person)
}
internal class PersonViewHolder(view: View) : RecyclerView.ViewHolder(view) {
var textViewName: TextView = view.findViewById(R.id.textViewNameDisplay)
var textViewEmail: TextView = view.findViewById(R.id.textViewEmailDisplay)
internal fun bind(person: Person) {
textViewEmail.text = person.email
textViewName.text = person.name
}
}
}
'私のアダプタでupdateDataを明示的に呼び出します。これを行うには、これが最善の方法か、最も効率的な方法かどうかはわかりません。いい方法はありますか?いいえ – EpicPandaForce