首页 > 代码库 > Android CursorAdapter的使用

Android CursorAdapter的使用

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

缺点:

  1. 直接把Cursor暴露在UI层,写了很多 cursor.getString(cursor.getColumnIndex("scheme"))类似的代码.直接把Cursor暴露在ui层是很不好的示范,Cursor是非常底层的数据模型,不应该暴露在ui层。
  2. SQLite 加载超过1M数据速度会变得很慢.一旦数据量大了整个UI的速度立刻降了下来。
  3. RecyclerView 并不支持 CursorAdapter

总之,CursorAdapter这种方式并不是很好的设计典范。

Android CursorAdapter的使用