Android:自定义光标适配器问题

发布于 2024-10-31 14:05:22 字数 2087 浏览 5 评论 0原文

我想知道是否有人能够为我指明正确的方向,或者帮我看看我的列表视图自定义光标适配器类出了什么问题。

基本上,我让它“工作”,因为它会用数据库中的名字填充列表视图,而不是移动到下一行。但是现在,它会抛出一个错误并且不会进入列表,所以任何感谢帮助。

基本上,我在实现时遇到的麻烦是从数据库读取名称和图像路径,并使用我的自定义适配器将其应用到 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);

非常感谢任何帮助。

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 CustomAdapter(this, R.layout.row, myCursor, new String[]{"animal_name"}, new int[]{R.id.animal});
    this.setListAdapter(mAdapter);

Any help is greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

枫以 2024-11-07 14:05:22

所有适配器类都可以遵循重写 getView() 的 ArrayAdapter 模式来定义
行。然而,CursorAdapter 及其子类有一个默认实现
getView()。
getView() 方法检查提供的要回收的视图。如果为 null,则调用 getView()
newView(),然后是bindView()。如果不为 null,则 getView() 仅调用 bindView()。
如果您正在扩展 CursorAdapter,它用于显示数据库或
内容提供者查询,您应该重写 newView() 和 bindView(),而不是
getView()。所有这一切都是删除你在 getView() 中的 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 
} 

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 
} 
浊酒尽余欢 2024-11-07 14:05:22

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

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

从 10,000 英尺开始,其工作方式如下
GetView如果view为null则调用newView,new view后调用bindView。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文