7

Sto utilizzando l'adattatore del cursore per la visualizzazione elenco. Stavo pensando di usare i resolver di contenuto per ottenere un cursore. Ora ho cambiato idea per dargli la possibilità di imparare il Reame.Ottieni il cursore utilizzando la libreria di Realm

Come posso ottenere oggetto "Cursore" utilizzando il dominio? A proposito, mi piacerebbe anche dare qualche frammento per ordinare il cursore.

Grazie.

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

}

risposta

7

Christian da Realm qui. Realm attualmente non espone un cursore anche se è qualcosa che vogliamo fare: https://github.com/realm/realm-java/issues/438

Se si desidera utilizzare un RecyclerView con Reame Vorrei raccomandare questo blogpost per un consiglio su come integrarli: http://gradlewhy.ghost.io/realm-results-with-recyclerview/

+0

È bello sentire gli aggiornamenti futuri :) Dove possiamo provare le build di istantanee? –

+0

Vedi questo per informazioni su come configurarlo: https://github.com/realm/realm-java/issues/936. L'ultimo -SNAPSHOT è 0.80.1 –

+0

è in MavenCentral? o il server Snapshot? –

3

Attualmente , penso che Realm non supporti l'architettura ContentProvider.

Ma, solo per abbinare sull'interfaccia Cursore, è possibile recuperare un risultato elenco da Reame e creare un MatrixCursor da questi dati.

Certo, non è la soluzione migliore per le prestazioni della RAM. Il supporto per i cursori è davvero una funzionalità necessaria in Realm.

0

Prova questo. Non è perfetto (io non so nemmeno cosa tutti i metodi cursore fanno ...), ma funziona per me:

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

quindi è possibile utilizzare le cose come:

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

Di Ovviamente se fai tutto il tuo lavoro sullo stesso thread puoi usare direttamente l'istanza realm invece di fare realm.copyFromRealm(fn(realm))