带有节标题

时间:2015-05-29 03:04:06

标签: android listview realm

我正在尝试使用Android的realm数据存储,我正在尝试构建一个应用程序,向用户显示ListView中的选项列表,有点像用户联系名单。每个部分的第一个字母(例如A,B,C等)应该是标题。有没有办法用RealmBaseAdapter来实现这个目标?

目前我使用ArrayAdapter并且我只是有一个填充了值的数组,但是如果可能的话,我想使用它的适配器从Realm中提取数据。我知道在iOS中使用NSFetchedResultsController相当直接。我们如何将RealmResults分解为几个部分?

2 个答案:

答案 0 :(得分:2)

RealmBaseAdapter不能使用ExpandableListAdapter(我假设您正在使用哪些部分?),所以现在您唯一的选择是创建自己的实现。但RealmResults也是一个List,所以它应该与ArrayAdapter无缝协作。

您还可以在此处查看更多详细信息:https://github.com/realm/realm-java/issues/978

答案 1 :(得分:0)

这就是我使用的:

position: realtive

用法:

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()
    }
}