7

Ich benutze Cursor-Adapter für meine Listenansicht. Ich hatte vor, Content-Resolver zu verwenden, um einen Cursor zu erhalten. Jetzt änderte ich meine Meinung, um ihm die Chance zu geben, das Reich zu lernen. Wie kann ich "Cursor" Objekt mit Realm erhalten? Übrigens würde ich mich auch freuen, ein paar Schnipsel zu geben, um den Cursor zu sortieren.Holen Sie den Cursor mit Realm-Bibliothek

Danke.

final class Contact extends RealmObject { 

private CharSequence mName; 


public CharSequence getName() { 
    return mName; 
} 

public void setName(CharSequence name) { 
    this.mName = name; 
} 

}

final class ContactListAdapter extends CursorRecyclerViewAdapter<ContactListAdapter.ContactHolder> implements View.OnClickListener { 

private OnContactClickListener mListener; 


public ContactListAdapter(Context context, Cursor cursor) { 
    super(context, cursor); 
} 

@Override 
public ContactHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View itemView = getLayoutInflater().inflate(R.layout.cell_contact, parent, false); 

    ContactHolder contactHolder = new ContactHolder(itemView); 
    contactHolder.mContactPhotoImageView.setOnClickListener(this); 

    return contactHolder; 
} 

@Override 
public void onBindViewHolder(ContactHolder viewHolder, Cursor cursor) { 
    viewHolder.mNameTextView.setText("Emre Akturk"); 

    int position = cursor.getPosition(); 
    viewHolder.mContactPhotoImageView.setImageResource(R.mipmap.ic_launcher); 
    viewHolder.mContactPhotoImageView.setTag(position); 
} 

@Override 
public int getItemCount() { 
    return 5; 
} 

public void setOnContactClickListener(OnContactClickListener callback) { 
    this.mListener = callback; 
} 

@Override 
public void onClick(View v) { 
    if (mListener == null) { 
     return; 
    } 

    int position = (int) v.getTag(); 
    if (position == -1) { 
     mListener.onContactCallClicked(v, getCursor(), position); 
    } else { 
     mListener.onContactAddClicked(v, position); 
    } 
} 

public interface OnContactClickListener { 
    void onContactCallClicked(View v, Cursor cursor, int position); 

    void onContactAddClicked(View v, int position); 
} 

protected class ContactHolder extends RecyclerView.ViewHolder { 
    private TextView mNameTextView; 
    private CircleImageView mContactPhotoImageView; 

    protected ContactHolder(View itemView) { 
     super(itemView); 
     mNameTextView = (TextView) itemView.findViewById(R.id.cell_contact_name_textview); 
     mContactPhotoImageView = (CircleImageView) itemView.findViewById(R.id.cell_contact_photo_imageview); 
    } 
} 

}

Antwort

7

Christian von Realm hier. Realm zur Zeit aussetzen keinen Cursor, obwohl es etwas ist, was wir tun wollen: https://github.com/realm/realm-java/issues/438

Wenn Sie einen RecyclerView mit Realm verwenden möchten würde ich diesen Blogpost um Rat empfehlen, wie sie integrieren: http://gradlewhy.ghost.io/realm-results-with-recyclerview/

+0

Es ist schön, zukünftige Updates zu hören :) Wo können wir Snapshot-Builds ausprobieren? –

+0

Hier finden Sie Informationen zur Einrichtung: https://github.com/realm/realm-java/issues/936. Letzter -SNAPSHOT ist 0.80.1 –

+0

ist es in MavenCentral? oder Snapshot-Server? –

3

Aktuell Ich denke, dass Realm die ContentProvider-Architektur nicht unterstützt.

Aber um nur auf der Cursor-Schnittstelle zu entsprechen, können Sie ein Listenergebnis aus Realm abrufen und aus diesen Daten ein MatrixCursor erstellen.

Sicher, ist nicht die beste Lösung für RAM-Leistung. Cursor-Unterstützung ist wirklich ein dringend benötigtes Feature in Realm.

0

Versuchen Sie dies. Es ist nicht perfekt (ich weiß nicht einmal, was alle Cursor Methoden tun ...), aber es funktioniert für mich:

open class DetachedRealmCursor<T : RealmModel>(val clazz: Class<T>, fn: (Realm) -> RealmResults<T>) : Cursor { 
    open val result: List<T> by lazy { 
     val realm = Realm.getDefaultInstance() 
     val list = realm.copyFromRealm(fn(realm)) 
     //val list = fn(realm) 
     realm.close() 
     closed = false 
     list 
    } 
    var current = 0 
    protected var notUri: Uri? = null 
    protected var contencontObservable = ContentObservable() 
    protected var datasetObservable = DataSetObservable() 

    private val columnTypes: List<Int> 
    private val columnNames: List<String> 
    private var extras : Bundle = Bundle.EMPTY 
    private var closed = true 

    val FIELD_TYPE_REALMLIST = Cursor.FIELD_TYPE_BLOB+1 

    init { 
     columnTypes = getFieldTypes() 
     columnNames = getFieldNames() 
    } 

    private fun getFieldNames(): List<String> { 
     return clazz.declaredFields?.map { 
      it.name 
     } ?: listOf("col1") 
    } 

    private fun getFieldTypes(): List<Int> { 
     return clazz.declaredFields?.map { 
      when (it.type) { 
       String::class.java -> Cursor.FIELD_TYPE_STRING 
       Float::class.java -> Cursor.FIELD_TYPE_FLOAT 
       Int::class.java -> Cursor.FIELD_TYPE_INTEGER 
       RealmList::class.java -> FIELD_TYPE_REALMLIST 
       else -> Cursor.FIELD_TYPE_NULL 
      } 
     } ?: listOf(Cursor.FIELD_TYPE_STRING) 
    } 

    private fun getValueFromColumn(col: Int, pos: Int): Any? { 
     val field = result[pos].javaClass.getDeclaredField(getColumnName(col)) 
     field.isAccessible = true 
     return field.get(result[pos]) 
    } 

    override fun moveToPosition(p0: Int): Boolean = 
      if (p0 >= -1 && p0 <= result.size) { 
       current = p0 
       true 
      } else 
       false 

    override fun moveToFirst(): Boolean = 
      if (result.isNotEmpty()) { 
       current = 0 
       true 
      } else false 

    override fun move(p0: Int): Boolean = if (p0 >= -1 && p0 <= result.size) { 
     current = p0 
     true 
    } else { 
     false 
    } 

    override fun moveToPrevious(): Boolean = if (current > -1) { 
     current-- 
     true 
    } else false 

    override fun moveToNext(): Boolean = if (current < result.size) { 
     current++ 
     true 
    } else false 

    override fun isBeforeFirst(): Boolean = current == -1 

    override fun moveToLast(): Boolean = if (result.isNotEmpty()) { 
     current = result.size - 1 
     true 
    } else false 

    override fun isAfterLast(): Boolean = current >= result.size 

    override fun getColumnIndexOrThrow(p0: String): Int { 
     val found = columnNames.indexOf(p0) 
     return if (found == -1) throw IllegalArgumentException() else found 
    } 

    override fun getColumnNames(): Array<String> = columnNames.toTypedArray() 

    override fun getType(p0: Int): Int = columnTypes[p0] 

    override fun getColumnName(p0: Int): String = columnNames[p0] 

    override fun getColumnIndex(p0: String?): Int = columnNames.indexOf(p0) 

    override fun getColumnCount(): Int = columnNames.size 

    override fun getNotificationUri(): Uri? = notUri 

    override fun deactivate() {} 

    override fun requery(): Boolean = true 

    override fun registerContentObserver(p0: ContentObserver) { 
     // Register an observer that is called when changes happen to the content backing this cursor. 
     // Typically the data set won't change until requery() is called. 
     contencontObservable.registerObserver(p0) 
    } 

    override fun registerDataSetObserver(p0: DataSetObserver) { 
     // Register an observer that is called when changes happen to the contents of the this 
     // cursors data set, for example, when the data set is changed via requery(), deactivate(), or close(). 
     datasetObservable.registerObserver(p0) 
    } 

    override fun unregisterContentObserver(p0: ContentObserver?) { 
     if(!closed) { 
      contencontObservable.unregisterObserver(p0) 
     } 
    } 

    override fun unregisterDataSetObserver(p0: DataSetObserver?) { 
     datasetObservable.unregisterObserver(p0) 
    } 

    override fun getWantsAllOnMoveCalls(): Boolean = false 

    override fun getPosition(): Int = current 

    override fun close() { 
     closed = true 
     contencontObservable.unregisterAll() 
     datasetObservable.notifyInvalidated() 
    } 

    override fun isClosed() = closed 

    override fun getCount(): Int = result.size 

    override fun isFirst(): Boolean = current == 1 

    override fun isLast(): Boolean { 
     return current == result.size - 1 
    } 

    override fun isNull(p0: Int): Boolean = getValueFromColumn(p0, current) == null 

    // poniższe można zamienić na getValueFromColumn 

    override fun getLong(p0: Int): Long = getValueFromColumn(p0, current) as Long 

    override fun getFloat(p0: Int): Float = getValueFromColumn(p0, current) as Float 

    override fun getInt(p0: Int): Int = getValueFromColumn(p0, current) as Int 

    override fun getBlob(p0: Int): ByteArray = getValueFromColumn(p0, current) as ByteArray 

    override fun getShort(p0: Int): Short = getValueFromColumn(p0, current) as Short 

    override fun getString(p0: Int): String = getValueFromColumn(p0, current) as String 

    override fun getDouble(p0: Int): Double = getValueFromColumn(p0, current) as Double 

    fun getList(p0: Int): RealmList<*> = getValueFromColumn(p0, current) as RealmList<*> 

    override fun setNotificationUri(p0: ContentResolver?, p1: Uri?) { 
     notUri = p1 
    } 

    override fun copyStringToBuffer(p0: Int, p1: CharArrayBuffer?) {} 

    override fun respond(extras: Bundle): Bundle = Bundle.EMPTY 

    override fun getExtras(): Bundle = extras 

    override fun setExtras(p0: Bundle) { 
     extras = p0 
    } 
} 

Dann können Sie es gerne verwenden:

val cursor = RealmCursor(RAlbum::class.java) { it.where(RAlbum::class.java).distinct("sTitle") }

Of Natürlich, wenn Sie alle Ihre Arbeit auf dem gleichen Thread können Sie direkt realm Instanz statt tun realm.copyFromRealm(fn(realm))

Verwandte Themen