如何随机播放RealmResults对象的内容

时间:2016-03-26 22:24:56

标签: android android-recyclerview realm

我有一个RealmResults对象,它保存.where.findAll()查询的输出。我在RecyclerView中显示此对象的内容,但由于RealmResults对象的内容是静态的,因此它会显示相同的记录集,并且打开RecyclerView。我想要随机化(随机化)RealmResults的内容,以便我可以在RecyclerView中显示RealmResults中的不同值。请提供一些可行的方法,以便我可以执行相同的操作。

2 个答案:

答案 0 :(得分:5)

你不应该随机化列表本身,你应该随机化你对它的访问(索引)。

构建包含[0, n-1]

索引的列表
List<Integer> indices = new ArrayList<>(realmResults.size());
for(int i = 0; i < realmResults.size(); i++) {
    indices.add(i);
}

随机播放

Collections.shuffle(indices);

然后,当您选择视图持有者数据时,使用索引随机位置

索引领域结果
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if(holder instanceof YourHolder) {
        YourHolder yourHolder = (YourHolder) holder;
        RealmData realmData = realmResults.get(indices.get(position));
        //init data for your holder
    }
}

答案 1 :(得分:0)

对于将来的引用,在扩展RealmRecyclerViewAdapter时,如果您启用了autoUpdate功能,则在更新的情况下上述解决方案是不够的。

这是一个基于相同想法的解决方案,处理更新。

这里我忽略了更新类型,只是在项目计数发生变化时重置整个混洗状态。要适应更具体的事件(itemRangeAdded,itemRangeRemoved,...)并不难,您只需要相应地更新indicesMapListdisplayedMapList

这个适配器处理混洗/排序,并准备好处理过滤(没有被问到,但是从我做的代码中删除了这个,你可以删除不必要的部分,如果不需要的话)。

(要过滤仅使用您要显示的项目索引更新displayedMapList,排序/随机播放操作将保留过滤器)

abstract class BaseRealmAdapter<T : RealmObject, S : RecyclerView.ViewHolder>(data: OrderedRealmCollection<T>,
                                                                              autoUpdate: Boolean) :
        RealmRecyclerViewAdapter<T, S>(data, autoUpdate) {

    private val indicesMapList = arrayListOf(*(0 until getRealItemCount()).toList().toTypedArray())
    val displayedMapList = ArrayList(indicesMapList)
    var shuffled = false
        private set

    /** Displayed item count (after possible filter) */
    override fun getItemCount() = displayedMapList.size

    override fun getItem(index: Int) = super.getItem(displayedMapList[index])

    /** Unfiltered item count */
    fun getRealItemCount() = super.getItemCount()

    fun shuffle() {
        if (getRealItemCount() == 0)
            return
        shuffled = true
        Collections.shuffle(indicesMapList)
        // Keep same order
        displayedMapList.sortBy { indicesMapList.indexOf(it) }
        notifyDataSetChanged()
    }

    fun sort() {
        if (getRealItemCount() == 0)
            return
        shuffled = false
        indicesMapList.sort()
        displayedMapList.sort()
        notifyDataSetChanged()
    }

    protected fun resetIndicesMap(notifyDataSetChanged: Boolean = true) {
        shuffled = false
        indicesMapList.clear()
        indicesMapList.addAll(0 until getRealItemCount())
        resetDisplayedList()

        if (notifyDataSetChanged)
            notifyDataSetChanged()
    }

    protected fun resetDisplayedList() {
        displayedMapList.clear()
        displayedMapList.addAll(indicesMapList)
    }

    protected fun getIndicesMapList() = ArrayList(indicesMapList)

    override fun onAttachedToRecyclerView(recyclerView: RecyclerView?) {
        registerAdapterDataObserver(DataObserver())
        super.onAttachedToRecyclerView(recyclerView)
    }

    /** This implementation will cancel any current shuffled state when adding items */
    inner class DataObserver : RecyclerView.AdapterDataObserver() {
        override fun onChanged() {
            // Item(s) added or removed: this will cancel filtering
            if (getRealItemCount() != indicesMapList.size)
                resetIndicesMap(true)
        }
    }
}