RecyclerView.ViewHolder
RecyclerView.Adapter
LayoutManager
LinearLayoutManager
GridLayoutManager
StaggeredGridLayoutManager
RecyclerView.ItemDecoration
RecyclerView.ItemAnimator
DefaultItemAnimator
ItemTouchHelper
SnapHelper
RecyclerView.RecycledViewPool
CursorAdapter
hold a CursorAdapter member in my recyclerView.Adapter implementation. Then passing all the handling of creating the new view & binding it to the cursor adapter
public class MyRecyclerAdapter extends Adapter<MyRecyclerAdapter.ViewHolder> {
// Because RecyclerView.Adapter in its current form doesn't natively
// support cursors, we wrap a CursorAdapter that will do all the job
// for us.
CursorAdapter mCursorAdapter;
Context mContext;
public MyRecyclerAdapter(Context context, Cursor c) {
mContext = context;
mCursorAdapter = new CursorAdapter(mContext, c, 0) {
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// Inflate the view here
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
// Binding operations
}
};
}
public static class ViewHolder extends RecyclerView.ViewHolder {
View v1;
public ViewHolder(View itemView) {
super(itemView);
v1 = itemView.findViewById(R.id.v1);
}
}
@Override
public int getItemCount() {
return mCursorAdapter.getCount();
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
// Passing the binding operation to cursor loader
mCursorAdapter.getCursor().moveToPosition(position); //EDITED: added this line as suggested in the comments below, thanks :)
mCursorAdapter.bindView(holder.itemView, mContext, mCursorAdapter.getCursor());
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// Passing the inflater job to the cursor-adapter
View v = mCursorAdapter.newView(mContext, mCursorAdapter.getCursor(), parent);
return new ViewHolder(v);
}
}
SimpleCursorAdapter参数之谜
简书作者:zzh0838,原文链接:http://www.jianshu.com/p/daadc9d2bf1a
Question
SimpleCursorAdapter的构造函数是
SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags);
最后一个参数可选的值有:
- FLAG_AUTO_REQUERY (这个值在Api 11 以后(包含)被弃用了,不用管)
- FLAG_REGISTER_CONTENT_OBSERVER
- 0
那到底应该选哪一个呢(虽然只是二选一)?没错,我懵逼了。这个时候,当然是google来帮忙,stackOverFlow搜一搜,but,but,but,搜到的内容都很简略,没人告诉我,我在写SimpleCursorAdapter的时候应该传哪一个参数。
Answer
自己看源码喽,先看看继承继承关系吧(来至官方文档):
java.lang.Object
↳ android.widget.BaseAdapter
↳ android.widget.CursorAdapter
↳ android.widget.ResourceCursorAdapter
↳ android.widget.SimpleCursorAdapter
好吧,先看看SimpleCursorAdapter的默认构造函数吧
public SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from,
int[] to, int flags) {
super(context, layout, c, flags);
mTo = to;
mOriginalFrom = from;
findColumns(c, from);
}
可以看到flags传到了父类ResourceCursorAdapter的构造函数。那我们去看看吧。
public ResourceCursorAdapter(Context context, int layout, Cursor c, int flags) {
super(context, c, flags);
mLayout = mDropDownLayout = layout;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mDropDownInflater = mInflater;
}
flags又传到父类CursorAdapter了,再去看看:
public CursorAdapter(Context context, Cursor c, int flags){
init(context, c, flags);
}
调用了init:
void init(Context context, Cursor c, int flags) {
if ((flags & FLAG_AUTO_REQUERY) == FLAG_AUTO_REQUERY) {
flags |= FLAG_REGISTER_CONTENT_OBSERVER;
mAutoRequery = true;
} else {
mAutoRequery = false;
}
boolean cursorPresent = c != null;
mCursor = c;
mDataValid = cursorPresent;
mContext = context;
mRowIDColumn = cursorPresent ? c.getColumnIndexOrThrow("_id") : -1;
if ((flags & FLAG_REGISTER_CONTENT_OBSERVER) == FLAG_REGISTER_CONTENT_OBSERVER) {
mChangeObserver = new ChangeObserver();
mDataSetObserver = new MyDataSetObserver();
} else {
mChangeObserver = null;
mDataSetObserver = null;
}
if (cursorPresent) {
if (mChangeObserver != null) c.registerContentObserver(mChangeObserver);
if (mDataSetObserver != null) c.registerDataSetObserver(mDataSetObserver);
}
}
函数有点长,假设我们的flags设置成了 0,不会有什么操作,假设我们的flags设置成了FLAG_REGISTER_CONTENT_OBSERVER, 那么接下来会构造两个Observer:
mChangeObserver = new ChangeObserver();
mDataSetObserver = new MyDataSetObserver();
并且在cursor不为null的时候将这两个Observer注册给cusor。
if (mChangeObserver != null) c.registerContentObserver(mChangeObserver);
if (mDataSetObserver != null) c.registerDataSetObserver(mDataSetObserver);
那么问题来了,什么时候这两个Observer才会被触发呢?看看Cursor文档吧,文档了这么说的。
当调用方法requery()时,会触发ContentObserver。
当调用方法requery(), deactivate(), or close()时,DataSetObserver会被触发。
然后继续看文档,requery(), deactivate()都被弃用了。调用close后,cursor就没了(Closes the Cursor, releasing all of its resources and making it completely invalid.)。我尼玛,我尼玛,我尼玛,我心里一万只草泥马在奔腾,都不用看两个Observer定义的操作了。传这个参数压根就没什么鸟用。lz彻底懵逼了。
好了,现在可以下结论了:flag永远传0就可以了