Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/205.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 带节头的RealmBaseAdapter_Android_Listview_Realm - Fatal编程技术网

Android 带节头的RealmBaseAdapter

Android 带节头的RealmBaseAdapter,android,listview,realm,Android,Listview,Realm,我正在尝试使用Android的领域数据存储,我正在尝试构建一个应用程序,向用户显示列表视图中的选项列表,有点像用户联系人列表。每个部分(如A、B、C等)的第一个字母应为标题。有没有办法通过RealmBaseAdapter实现这一点 目前,我使用的是ArrayAdapter,我只是使用一个填充了值的数组,但如果可能的话,我希望使用它的适配器从域中提取数据。我知道在iOS中,使用NSFetchedResultsController,这是相当直接的。如何将RealmResults分解为多个部分?Rea

我正在尝试使用Android的
领域
数据存储,我正在尝试构建一个应用程序,向用户显示
列表视图
中的选项列表,有点像用户联系人列表。每个部分(如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的领域版本的用例,这对于类似的东西是需要的。我已将其添加到我们的积压工作中: