Android RealmRecyclServiceAdapter中未反映领域查询更新

Android RealmRecyclServiceAdapter中未反映领域查询更新,android,realm,Android,Realm,一直在使用领域和它的真棒 遇到了什么事。想知道我是否做错了什么 我有一个realmRecyclServiceAdapter,用于显示领域查询的结果。如果我在域中添加或更新记录,这将非常有效。我必须在recycler视图上设置hasFixedSize(false),才能让它动态更新。不确定这是否正确,但它起了作用 不管怎样,这不是我的问题 我正在尝试过滤我的数据。我有以下疑问: realm.where(Person::class.java).contains("name", nameFilter,

一直在使用领域和它的真棒

遇到了什么事。想知道我是否做错了什么

我有一个
realmRecyclServiceAdapter
,用于显示领域查询的结果。如果我在域中添加或更新记录,这将非常有效。我必须
在recycler视图上设置hasFixedSize(false)
,才能让它动态更新。不确定这是否正确,但它起了作用

不管怎样,这不是我的问题

我正在尝试过滤我的数据。我有以下疑问:

realm.where(Person::class.java).contains("name", nameFilter, Case.INSENSITIVE).findAllSorted("name")
我正在将此RealmResults传递给我的recycler视图,它在添加/更新方面非常有效

但是,当我尝试筛选时,它不会自动更新

我说的对吗?仅仅更改我的过滤器(由
nameFilter
指定)不足以重新运行查询?我想这是很公平的。因为我猜没有触发器让realm知道我已经更改了字符串的值

但是,即使我重新计算查询,它似乎也不会在Recycler视图中更新,除非我在适配器上显式调用
updateData
。我不确定这是最好的还是最有效的方法。有更好的办法吗

完整代码:

主要活动

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))
    }
}
class MainActivity:AppCompatActivity(),View.OnClickListener{
private val TAG:String=this::class.java.simpleName
private val realm:realm=realm.getInstance(RealmConfiguration.Builder().DeleteRealMifMigrationRequired().build())
私有变量nameFilter=“”
私有变量allPersons:RealmResults=realm.where(Person::class.java).contains(“名称”,nameFilter,不区分大小写).findAllSorted(“名称”)
专用val适配器:PersonRecycleServiceAdapter=PersonRecycleServiceAdapter(所有人)
私有lateinit var一次性:一次性
重写创建时的乐趣(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
realm.executeTransaction({
//realm.deleteAll()
})
Log.i(标记“从域中删除所有对象”)
ButtonAdorUpdatePerson.setOnClickListener(此)
setUpRecyclerView()
一次性=RxTextView.textChangeEvents(editTextNameFilter)
//.debounce(400,TimeUnit.millises)//默认调度程序为计算
.observeOn(AndroidSchedulers.mainThread())
.subscribowith(getSearchObserver())
}
private fun getSearchObserver():DisposableObserver{
返回对象:DisposableObserver(){
覆盖有趣的onComplete(){
Log.i(标记“------------onComplete”)
}
覆盖有趣的错误(e:可丢弃){
Log.i(标记“-----------Woops on error!”)
}
覆盖onNext(onTextChangeEvent:TextViewTextChangeEvent){
nameFilter=editTextNameFilter.text.toString()
allPersons=realm.where(Person::class.java)。包含(“名称”,名称过滤器,不区分大小写)。findAllSorted(“名称”)
//这是必需的,否则“回收器”视图不会更新
adapter.updateData(所有人)
Log.d(标记“过滤器:$nameFilter”)
}
}
}
重写onDestroy(){
super.ondestory()
realm.close()
}
覆盖趣味onClick(视图:视图?){
if(view==null)返回
何时(查看){
按钮ADORUPDATEPERSON->handleAddOrUpdatePerson()
}
}
私人娱乐handleAddOrUpdatePerson(){
val personToAdd=Person()
personToAdd.name=editTextName.text.toString()
personToAdd.email=editTextEmail.text.toString()
realm.executeTransactionAsync({
bgRealm->bgRealm.copyToRealmOrUpdate(个人添加)
})
}
私人娱乐设置回收视图(){
recyclerViewPersons.layoutManager=LinearLayoutManager(此)
RecycleServiceWPersons.adapter=适配器
recyclerViewPersons.setHasFixedSize(false)
RecycleServiceWPersons.addItemDecoration(DividerItemDecoration(此为LinearLayoutManager.VERTICAL))
}
}
PersonRecycleServiceAdapter

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
        }
    }
}
内部类PersonRecycleServiceAdapter(数据:OrderedRealmCollection?,自动更新:Boolean=true):RealmRecycleServiceAdapter(数据,自动更新){
override onCreateViewHolder(父级:ViewGroup,viewType:Int):PersonViewHolder{
val itemView=LayoutInflater.from(parent.context)。充气(R.layout.person\u行,parent,false)
return PersonViewHolder(项目视图)
}
覆盖onBindViewHolder(holder:PersonViewHolder?,位置:Int){
if(holder==null | | data==null)返回
val personList=数据?:返回
val person=个人列表[职位]
持票人(人)
}
内部类PersonViewHolder(视图:视图):RecyclerView.ViewHolder(视图){
变量textViewName:TextView=view.findViewById(R.id.textViewNameDisplay)
var textViewEmail:TextView=view.findViewById(R.id.textViewEmailDisplay)
内部趣味绑定(个人:个人){
textViewEmail.text=person.email
textViewName.text=person.name
}
}
}
是的,
updateData()
就是这样做的。由于更新了查询,因此要显示的
结果
将成为不同的对象<必须调用code>updateData(),以通知适配器数据源已更改

但是,您可能会以这种方式丢失RecyclerView的漂亮动画,因为由于数据源已更改,整个视图将被刷新。有一些方法可以解决这个问题

例如:您可以将一个字段
isSelected
添加到
Person
。通过
isSelected
字段查询结果并将其传递给适配器:

allPersons = realm.where(Person::class.java).equalTo("isSelected", true).findAllSorted("name")
adapter = PersonRecyclerViewAdapter(allPersons)
当改变q值时
realm.executeTransactionAsync({
    var allPersons = realm.where(Person::class.java).equalTo("isSelected", true).findAllSorted("name")
    for (person in allPersons) person.isSelected = false; // Clear the list first
    allPersons = realm.where(Person::class.java).contains("name", nameFilter, Case.INSENSITIVE).findAllSorted("name") // new query
    for (person in allPersons) person.isSelected = true;
    })