开发者

Android: Custom Cursor Adapter Trouble

I am wondering if someone may be able to point me in the right direction or lend a pair of eyes and see where I am going wrong with my custom cursor adapter class for a listview.

Basically, I had it "working", in the sense that it would populate the listview with the firstname from the database, and not move to the next row.Now however, it will throw up an error and not enter into list, so any help is appreciated.

Basically what I am having trouble in achieving is reading a name and image path from database and apply it to a row.xml with my custom adapter.Here is my code:

public class CustomAdapter extends SimpleCursorAdapter {

private LayoutInflater mInflater;
private Context context;
private int layout;

//private Cursor c;
String animal_name;
String img_path;

public CustomAdapter(Context context,int layout, Cursor c, String[] from, int[] to){
super(context, layout, c, from, to);

//this.c = c;
this.context = context;
this.layout = layout;
}



@Override
public View getView(int position, View convertView, ViewGroup parent){

    View row = convertView;         
    ViewWrapper wrapper = null;

    Cursor c = getCursor();

    animal_name =  c.getString((c.getColumnIndexOrThrow(MyDBManager.KEY_ANIMALNAME)));
    img_path = c.getString((c.getColumnIndexOrThrow(MyDBManager.KEY_IMGPATH)));     

    if(row == null){
        LayoutInflater inflater = LayoutInflater.from(context); 

        row = inflater.inflate(R.layout.row, null);
        // row is passed in as "base" variable in ViewWrapper class.
        wrapper = new ViewWrapper(row);

        row.setTag(row);
    }
    else{ 
        wrapper=(ViewWrapper)row.getTag();
    }

    wrapper.getLabel().setText(animal_name);
    wrapper.getIcon().setImageResource(R.id.icon);

    return (row);
}       

}

class ViewWrapper{
View base;
TextView label = null;
ImageView icon = null;

ViewWrapper(View base){
    this.base = base;
}

TextView getLabel(){
    if(label== null){
        label=(TextView)base.findViewById(R.id.author);
    }
    return (label);
}

ImageView getIcon(){
    if(icon == null){
        icon=(ImageView)base.findViewById(R.id.icon);
    }
    return (icon);
}

}

and have been setting the adapter as follows

CustomAdapter mAdapter = new CustomAdapte开发者_Python百科r(this, R.layout.row, myCursor, new String[]{"animal_name"}, new int[]{R.id.animal});
    this.setListAdapter(mAdapter);

Any help is greatly appreciated.


All adapter classes can follow the ArrayAdapter pattern of overriding getView() to define the rows. However, CursorAdapter and its subclasses have a default implementation of getView(). The getView() method inspects the supplied View to recycle. If it is null, getView() calls newView(), then bindView(). If it is not null, getView() just calls bindView(). If you are extending CursorAdapter, which is used for displaying results of a database or content provider query, you should override newView() and bindView(), instead of getView(). All this does is remove your if() test you would have in getView() and put each branch of that test in an independent method, akin to the following:

public View newView(Context context, Cursor cursor, 
                ViewGroup parent) { 
  LayoutInflater inflater=context.getLayoutInflater(); 
  View row=inflater.inflate(R.layout.row, null); 
  ViewWrapper wrapper=new ViewWrapper(row);  
  row.setTag(wrapper); 
  return(row); 
} 

public void bindView(View row, Context context, Cursor cursor) { 
  ViewWrapper wrapper=(ViewWrapper)row.getTag(); 
  // actual logic to populate row from Cursor goes here 
} 


You problem is that you were doing row.setTag(row). You should setTag to ViewWrapper instead.

In cursor adapter, you should override bindview and newView instead of getView.

From 10,000 feet, the way it works is as follow GetView calls newView if the view is null, and call bindView after new view.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜