Android:自定义光标适配器麻烦

时间:2011-04-10 17:59:14

标签: android cursor adapter

我想知道是否有人可以指出我正确的方向或借出一双眼睛,看看我的自定义游标适配器类在列表视图中出错了。

基本上,我把它“工作”,因为它会用数据库中的firstname填充listview,而不是移动到下一行。但是,它会抛出错误而不进入列表,所以任何帮助都表示赞赏。

基本上我遇到的问题是从数据库中读取名称和图像路径并使用我的自定义适配器将其应用到row.xml。这是我的代码:

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

}

并且已按如下方式设置适配器

CustomAdapter mAdapter = new CustomAdapter(this, R.layout.row, myCursor, new String[]{"animal_name"}, new int[]{R.id.animal});
    this.setListAdapter(mAdapter);

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:3)

  

所有适配器类都可以遵循覆盖getView()的ArrayAdapter模式来定义   行。但是,CursorAdapter及其子类具有默认实现   getView()。   getView()方法检查提供的View以进行回收。如果为null,则getView()调用   newView(),然后是bindView()。如果它不为null,则getView()只调用bindView()。   如果要扩展CursorAdapter,它用于显示数据库的结果或   内容提供者查询,你应该覆盖newView()和bindView(),而不是   getView()。所有这一切都是删除你在getView()和put中的if()测试   该测试的每个分支采用独立的方法,类似于以下内容:

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 
} 

答案 1 :(得分:1)

你的问题是你在做row.setTag(行)。您应该将标签设置为ViewWrapper。

在游标适配器中,您应该覆盖bindview和newView而不是getView。

从10,000英尺开始,它的工作方式如下 如果视图为null,则GetView调用newView,并在新视图之后调用bindView。