CursorAdapter继承于BaseAdapter,为Cursor和ListView连接提供了桥梁。
首先看一下CursorAdapter的部分源码:
/** * @see android.widget.ListAdapter# getView(int, View, ViewGroup) */ public View getView( int position, View convertView, ViewGroup parent) { if (!mDataValid) { throw new IllegalStateException( "this should only be called when the cursor is valid"); } if (!mCursor.moveToPosition(position)) { throw new IllegalStateException( "couldn't move cursor to position " + position); } View v; if (convertView == null) { v = newView( mContext, mCursor, parent); } else { v = convertView; } bindView(v, mContext, mCursor); return v; }
可以看出CursorAdapter是继承了BaseAdapter后覆盖它的getView方法在getView方法中调用了newView和bindView方法,我们在写CursorAdapter时必须实现它的两个方法。
public abstract View newView (Context context, Cursor cursor, ViewGroup parent); public abstract void bindView(View view, Context context, Cursor cursor);
从源码可以看出:
- newView ( ):并不是每次都被调用的,它只在实例化的时候调用,数据增加的时候也会调用,但是在重绘(比如修改条目里的TextView的内容)的时候不会被调用
- bindView ( ):从代码中可以看出在绘制Item之前一定会调用bindView方法它在重绘的时候也同样被调用
继承CursorAdapter的示例部分代码:
@Override public View newView(Context context, Cursor cursor, ViewGroup parent) { ViewHolder viewHolder= new ViewHolder(); LayoutInflater inflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE ); View view=inflater.inflate(R.layout.item_contacts ,parent,false); viewHolder. tv_name=(TextView) view.findViewById(R.id.tv_showusername ); viewHolder. tv_phonenumber=(TextView) view.findViewById(R.id.tv_showusernumber ); view.setTag(viewHolder); Log. i("cursor" ,"newView=" +view); return view; } @Override public void bindView(View view, Context context, Cursor cursor) { Log. i("cursor" ,"bindView=" +view); ViewHolder viewHolder=(ViewHolder) view.getTag(); //从数据库中查询姓名字段 String name=cursor.getString(cursor.getColumnIndex(PersonInfo.NAME)); //从数据库中查询电话字段 String phoneNumber=cursor.getString(cursor.getColumnIndex(PersonInfo.PHONENUMBER)); viewHolder. tv_name.setText(name); viewHolder. tv_phonenumber.setText(phoneNumber); }
缺点:
- 直接把Cursor暴露在UI层,写了很多
cursor.getString(cursor.getColumnIndex("scheme"))
类似的代码.直接把Cursor暴露在ui层是很不好的示范,Cursor是非常底层的数据模型,不应该暴露在ui层。 - SQLite 加载超过1M数据速度会变得很慢.一旦数据量大了整个UI的速度立刻降了下来。
- RecyclerView 并不支持 CursorAdapter
总之,CursorAdapter这种方式并不是很好的设计典范。