Android 带节头的RealmBaseAdapter
我正在尝试使用Android的Android 带节头的RealmBaseAdapter,android,listview,realm,Android,Listview,Realm,我正在尝试使用Android的领域数据存储,我正在尝试构建一个应用程序,向用户显示列表视图中的选项列表,有点像用户联系人列表。每个部分(如A、B、C等)的第一个字母应为标题。有没有办法通过RealmBaseAdapter实现这一点 目前,我使用的是ArrayAdapter,我只是使用一个填充了值的数组,但如果可能的话,我希望使用它的适配器从域中提取数据。我知道在iOS中,使用NSFetchedResultsController,这是相当直接的。如何将RealmResults分解为多个部分?Rea
领域
数据存储,我正在尝试构建一个应用程序,向用户显示列表视图
中的选项列表,有点像用户联系人列表。每个部分(如A、B、C等)的第一个字母应为标题。有没有办法通过RealmBaseAdapter
实现这一点
目前,我使用的是
ArrayAdapter
,我只是使用一个填充了值的数组,但如果可能的话,我希望使用它的适配器从域中提取数据。我知道在iOS中,使用NSFetchedResultsController
,这是相当直接的。如何将RealmResults
分解为多个部分?RealmBaseAdapter不适用于ExpandableListAdapter(我假设您正在使用ExpandableListAdapter进行部分),因此现在您唯一的选择是创建自己的实现。但RealmResults也是一个列表,因此它应该与ArrayAdapter无缝配合
您还可以在此处查看更多详细信息:这是我使用的:
package com.poterion.android.library.adapters
import android.widget.BaseExpandableListAdapter
import io.realm.*
/**
* @author Jan Kubovy <jan@kubovy.eu>
*/
abstract class RealmExpandableListAdapter<out Group : Any, Item : RealmModel>(
private val itemGroupsProvider: (Item) -> Collection<Group?>,
private val groupsProvider: (Collection<Item>) -> List<Group?>,
private var adapterData: OrderedRealmCollection<Item>?) : BaseExpandableListAdapter() {
private val listener: RealmChangeListener<OrderedRealmCollection<Item>>?
protected val groups: List<Group?>
get() {
return adapterData?.takeIf { isDataValid }?.let(groupsProvider) ?: emptyList()
}
private val isDataValid: Boolean
get() = adapterData?.isValid == true
init {
if (adapterData?.isManaged == false)
throw IllegalStateException("Only use this adapter with managed list, for un-managed lists you can just use the BaseAdapter")
this.listener = RealmChangeListener { notifyDataSetChanged() }
adapterData?.takeIf { isDataValid }?.also { addListener(it) }
}
private fun addListener(data: OrderedRealmCollection<Item>) {
when (data) {
is RealmResults<Item> -> data.addChangeListener((listener as RealmChangeListener<RealmResults<Item>>))
is RealmList<Item> -> data.addChangeListener((listener as RealmChangeListener<RealmList<Item>>))
else -> throw IllegalArgumentException("RealmCollection not supported: " + data.javaClass)
}
}
private fun removeListener(data: OrderedRealmCollection<Item>) {
when (data) {
is RealmResults<Item> -> data.removeChangeListener((listener as RealmChangeListener<RealmResults<Item>>))
is RealmList<Item> -> data.removeChangeListener((listener as RealmChangeListener<RealmList<Item>>))
else -> throw IllegalArgumentException("RealmCollection not supported: " + data.javaClass)
}
}
override fun getGroupCount(): Int = groups.size
override fun getChildrenCount(groupPosition: Int): Int = adapterData?.takeIf { isDataValid }?.let { data ->
val g = groups[groupPosition]
data.filter { g == null || groups(it).contains(g) }.size
} ?: 0
override fun getGroup(groupPosition: Int): Group? = if (groups.size > groupPosition) groups[groupPosition] else null
override fun getChild(groupPosition: Int, childPosition: Int): Item? = children(groupPosition)
.takeIf { it.size > childPosition }?.get(childPosition)
override fun notifyDataSetChanged() {
super.notifyDataSetChanged()
}
private fun children(groupPosition: Int): List<Item> {
return getGroup(groupPosition)
?.let { g -> adapterData?.takeIf { isDataValid }?.filter { groups(it).contains(g) } } ?: emptyList()
}
}
包com.poterion.android.library.adapters
导入android.widget.BaseExpandableListAdapter
导入io.realm*
/**
*@作者Jan Kubovyjan@kubovy.eu
*/
抽象类RealmExpandableListAdapter(
私有val项目组Provider:(项目)->集合,
私有val组Provider:(集合)->列表,
私有变量适配器数据:OrderedRealmCollection?:BaseExpandableListAdapter(){
私有val侦听器:RealmChangeListener?
受保护的val组:列表
得到(){
返回adapterData?takeIf{isDataValid}?let(groupsProvider)?:emptyList()
}
私有值isDataValid:布尔值
get()=adapterData?.isValid==true
初始化{
if(adapterData?.isManaged==假)
抛出IllegalStateException(“仅将此适配器与托管列表一起使用,对于非托管列表,您只能使用BaseAdapter”)
this.listener=RealmChangeListener{notifyDataSetChanged()}
adapterData?.takeIf{isDataValid}?也可以{addListener(it)}
}
private fun addListener(数据:OrderedRealmCollection){
何时(数据){
是RealmResults->data.addChangeListener((作为RealmChangeListener的侦听器))
是RealmList->data.addChangeListener((作为RealmChangeListener的侦听器))
else->抛出IllegalArgumentException(“不支持RealmCollection:”+data.javaClass)
}
}
private fun removeListener(数据:OrderedRealmCollection){
何时(数据){
是RealmResults->data.removeChangeListener((作为RealmChangeListener的侦听器))
是RealmList->data.removeChangeListener((作为RealmChangeListener的侦听器))
else->抛出IllegalArgumentException(“不支持RealmCollection:”+data.javaClass)
}
}
重写getGroupCount():Int=groups.size
重写fun getChildrenCount(groupPosition:Int):Int=adapterData?.takeIf{isDataValid}?.let{data->
val g=组[groupPosition]
data.filter{g==null | |组(it).contains(g)}.size
} ?: 0
重写组(groupPosition:Int):组?=if(groups.size>groupPosition)组[groupPosition]else null
重写fun getChild(groupPosition:Int,childPosition:Int):项?=子项(groupPosition)
.takeIf{it.size>childPosition}?.get(childPosition)
覆盖数据设置更改(){
super.notifyDataSetChanged()
}
私人娱乐儿童(组位置:Int):列表{
返回getGroup(groupPosition)
?.let{g->adapterData?.takeIf{isDataValid}?.filter{groups(it).contains(g)}?:emptyList()
}
}
使用方法:
class PersonListAdapter(realm: Realm) :
RealmExpandableListAdapter<String, Person>(
itemGroupsProvider = { person -> arrayOf(person.group, null) },
groupsProvider = { people -> people.map { it.group } },
adapterData = realm.where(Person::class.java)
.findAllSortedAsync("lastName", Sort.ASCENDING, "firstName", Sort.ASCENDING)) {
override fun getGroupId(groupPosition: Int) = getGroup(groupPosition).id
override fun getChildId(groupPosition: Int, childPosition: Int) = getChild(groupPosition, childPosition).id
override fun hasStableIds() = true
override fun getGroupView(groupPosition: Int, isExpanded: Boolean, convertView: View?, parent: ViewGroup?): View {
// ... Item View here ...
}
override fun getChildView(groupPosition: Int, childPosition: Int, isLastChild: Boolean,
convertView: View?, parent: ViewGroup?): View {
// ... Group View here ...
}
override fun isChildSelectable(groupPosition: Int, childPosition: Int) = true
}
class PersonListAdapter(领域:领域):
RealmExpandableListAdapter(
itemGroupsProvider={person->arrayOf(person.group,null)},
groupsProvider={people->people.map{it.group},
adapterData=realm.where(Person::class.java)
.findAllSortedAsync(“lastName”,Sort.升序,“firstName”,Sort.升序)){
覆盖getGroupId(groupPosition:Int)=getGroup(groupPosition).id
覆盖getChildId(groupPosition:Int,childPosition:Int)=getChild(groupPosition,childPosition).id
重写表ID()=true
覆盖有趣的getGroupView(groupPosition:Int,isExpanded:Boolean,convertView:View?,父级:ViewGroup?:View){
//…项目视图在此。。。
}
覆盖趣味getChildView(groupPosition:Int,childPosition:Int,isLastChild:Boolean,
convertView:视图?,父级:视图组?:视图{
//…这里的组视图。。。
}
override fun isChildSelectable(groupPosition:Int,childPosition:Int)=真
}
这是否在未来的计划中?我可以通过列表来做。但问题是,当你有一个非常大的列表(10000多个项目)时,这样做是没有效率的。我们目前没有任何计划,但我可以看到BaseExpandableListAdapter的领域版本的用例,这对于类似的东西是需要的。我已将其添加到我们的积压工作中: