2015-05-29 24 views
5

Android için realm veri deposunu kullanmaya çalışıyorum ve kullanıcıya, kullanıcıların iletişim listesi gibi bir ListView türünde bir seçenekler listesi görüntülemeye çalışan bir uygulama oluşturmaya çalışıyorum. Her bölüm için ilk harf (A, B, C, vb.) Bir başlık olmalıdır. Bunu RealmBaseAdapter ile başarmanın bir yolu var mı?Bölüm üstbilgileriyle birlikte RealmBaseAdapter

Şu anda ArrayAdapter ile çalışıyorum ve yalnızca değerlerin bulunduğu bir dizilim var ancak Mümkünse bağdaştırıcısını kullanarak Realm'den verileri almak istiyorum. IOS'ta biliyorum bu NSFetchedResultsController kullanarak oldukça doğru. RealmResults'u bölümlere nasıl ayırabiliriz?

cevap

2

RealmBaseAdapter, ExpandableListAdapter (bölümler için kullanıyor olduğunuzu farz ediyorum) ile çalışmıyor, bu yüzden tek seçenek kendi uygulamanızı oluşturuyor. Ancak bir RealmResults aynı zamanda bir Listedir, bu yüzden bir ArrayAdapter ile sorunsuz bir şekilde çalışmalıdır. https://github.com/realm/realm-java/issues/978

+0

bu gelecek için planları var mı

Ayrıca buradan daha fazla ayrıntı görebilir? Bunu listeden yapabilirim. Ancak sorun şu ki, çok geniş bir listeye (10.000+ öğe) sahip olduğunuzda, bunu bu şekilde yapmak için verimli değil. – KVISH

+0

Geçerli bir planımız yok, ancak böyle bir şey için gerekli olan BaseExpandableListAdapter'ın bir Realm sürümü için kullanım durumunu görebiliyorum. İş birikimlerimize ekledim: https://github.com/realm/realm-java/issues/1199 –

0

Bu kullandığım budur:

package com.poterion.android.library.adapters 

import android.widget.BaseExpandableListAdapter 
import io.realm.* 

/** 
* @author Jan Kubovy <[email protected]> 
*/ 
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() 
    } 
} 

Ve kullanımı:

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 
}