我正在使用游标适配器作为列表视图。我打算使用内容解析器来获取光标。现在我改变了主意,让它有机会学习Realm。
如何使用realm获取“Cursor”对象?顺便说一句,我也很乐意给几个片段来分类光标。
感谢。
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);
}
}
}
答案 0 :(得分:7)
来自境界的克里斯蒂安。虽然我们想要做的事情,Realm目前还没有公开Cursor:https://github.com/realm/realm-java/issues/438
如果你想在Realm上使用RecyclerView,我会推荐这篇博文来获取有关如何整合它们的建议:http://gradlewhy.ghost.io/realm-results-with-recyclerview/
答案 1 :(得分:3)
目前,我认为Realm不支持ContentProvider架构。
但是,为了匹配Cursor接口,您可以从Realm获取列表结果并从此数据创建MatrixCursor。
当然,这不是RAM性能的最佳解决方案。游标支持实际上是Realm上非常需要的功能。
答案 2 :(得分:0)
试试这个。它并不完美(我甚至不知道所有Cursor方法的功能......),但它对我有用:
SELECT
user0_.ID_PRINCIPAL AS ID1_3_,
user0_.VERSION AS VERSION3_,
user0_.NO_PRINCIPAL AS NO4_3_,
user0_.IN_BLOQUEO AS IN5_3_,
user0_.IN_ACTIVO AS IN6_3_
FROM JAAS_PRINCIPAL user0_
WHERE user0_.TT_DISCRIMINANTE = 'USER' AND user0_.NO_PRINCIPAL =?
然后你就可以使用它:
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
}
}
当然,如果您在同一个主题上完成所有工作,则可以直接使用val cursor = RealmCursor(RAlbum::class.java)
{ it.where(RAlbum::class.java).distinct("sTitle") }
个实例,而不是realm