使用ViewHolder模式单击问题但不使用getView

时间:2015-03-12 00:15:09

标签: android listview adapter android-viewholder

我将适配器代码从基本getView()更改为ViewHolder模式。我的适配器有一个TextView,一个ImageView和一个ImageButton。一切都很好但我在ImageButton遇到了一些问题。我会发布我的代码(getView()的代码和ViewHolder的代码)。 getView()的人工作得很好,所以我在这里问我因为我无法理解我在ViewHolder {{1}中做错了什么}}

带getView()的适配器类

ImageButton

使用ViewHolder的适配器类

public class ListAdapter extends ArrayAdapter<Manga> {
    private final Context context;
    private List<Manga> list;
    DatabaseHandler dh;
    SQLiteDatabase db;
    ArrayList<MangaPreferito> mangaPrefAL;
    int current_id = 0;

    public ListAdapter(Context context, List<Manga> list) {
        super(context, R.layout.listadapter, list);

        this.context = context;
        this.list = list;
    }


    @Override
    public View getView(final int position, View rowView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        rowView = inflater.inflate(R.layout.listadapter, parent, false);

        dh = new DatabaseHandler(context);
        db = dh.getWritableDatabase();
        mangaPrefAL = dh.getAllPreferiti(db);

        TextView titolo = (TextView) rowView.findViewById(R.id.textView);
        ImageView immagine = (ImageView) rowView.findViewById(R.id.imageView);
        final ImageButton ibFavorite = (ImageButton) rowView.findViewById(R.id.imageView2);

        if (list.get(position).getFavorite()) {
            ibFavorite.setBackgroundResource(R.drawable.icon_star);
        } else {
            ibFavorite.setBackgroundResource(R.drawable.favorite_icon_no);
        }

        for (MangaPreferito m : mangaPrefAL) {
            if (list.get(position).getI().equals(m.getI())) {
                list.get(position).setFavorite(true);
            }
        }
        //HERE ONCLICK WORKS WELL

        ibFavorite.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                for (MangaPreferito m : mangaPrefAL) {
                    if (list.get(position).getI().equals(m.getI())) {
                        current_id = m.getId();
                    }
                }

                if (list.get(position).getFavorite()) {
                    list.get(position).setFavorite(false);
                    ibFavorite.setBackgroundResource(R.drawable.favorite_icon_no);
                    dh.deleteManga(current_id, db);
                } else {
                    list.get(position).setFavorite(true);
                    ibFavorite.setBackgroundResource(R.drawable.icon_star);
                    dh.addPreferito(new MangaPreferito(list.get(position).getA(),
                            Integer.parseInt(String.valueOf(list.get(position).getH())),
                            list.get(position).getI(),
                            list.get(position).getIm(),
                            Double.parseDouble(String.valueOf(list.get(position).getLd())),
                            Integer.parseInt(String.valueOf(list.get(position).getS())), list.get(position).getT()), db);

                }
            }
        });

        return rowView;
    }
}

正如您所看到的public class ListAdapter extends ArrayAdapter<Manga> { private final Context context; private List<Manga> list; DatabaseHandler dh; SQLiteDatabase db; ArrayList<MangaPreferito> mangaPrefAL; int current_id = 0; ViewHolder viewHolder; public ListAdapter(Context context, List<Manga> list) { super(context, R.layout.listadapter, list); this.context = context; this.list = list; } static class ViewHolder{ TextView titolo; ImageView immagine; ImageButton ibFavorite; } @Override public View getView(final int position, View rowView, ViewGroup parent) { dh = new DatabaseHandler(context); db = dh.getWritableDatabase(); mangaPrefAL = dh.getAllPreferiti(db); if(rowView==null){ LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); rowView = inflater.inflate(R.layout.listadapter, parent, false); viewHolder = new ViewHolder(); viewHolder.titolo = (TextView) rowView.findViewById(R.id.textView); viewHolder.immagine = (ImageView) rowView.findViewById(R.id.imageView); viewHolder.ibFavorite = (ImageButton)rowView.findViewById(R.id.imageView2); rowView.setTag(viewHolder); } else { viewHolder = (ViewHolder) rowView.getTag(); } if(list.get(position).getFavorite()){ viewHolder.ibFavorite.setBackgroundResource(R.drawable.icon_star); }else{ viewHolder.ibFavorite.setBackgroundResource(R.drawable.favorite_icon_no); } for(MangaPreferito m : mangaPrefAL){ if (list.get(position).getI().equals(m.getI())) { list.get(position).setFavorite(true); } } //HERE ONCLICK DOESN'T WORK viewHolder.ibFavorite.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { for(MangaPreferito m : mangaPrefAL){ if (list.get(position).getI().equals(m.getI())) { current_id = m.getId(); } } if(list.get(position).getFavorite()){ list.get(position).setFavorite(false); viewHolder.ibFavorite.setBackgroundResource(R.drawable.favorite_icon_no); dh.deleteManga(current_id, db); }else{ list.get(position).setFavorite(true); viewHolder.ibFavorite.setBackgroundResource(R.drawable.icon_star); dh.addPreferito(new MangaPreferito(list.get(position).getA(), Integer.parseInt(String.valueOf(list.get(position).getH())), list.get(position).getI(), list.get(position).getIm(), Double.parseDouble(String.valueOf(list.get(position).getLd())), Integer.parseInt(String.valueOf(list.get(position).getS())),list.get(position).getT()), db); } } }); return rowView; } } 内的代码相同但onClick()内的代码不起作用,有人可以解释一下原因吗? 附:如果您需要更多代码或课程,请告诉我,我将编辑我的答案。

1 个答案:

答案 0 :(得分:4)

遵循此策略以正确使用具有视图持有者模式的点击侦听器:

  • 使您的OnClickListener成为您的类的成员,超出getView(...)调用的范围。这样可以确保您在认为有闭包时没有问题(因此您不再需要将位置声明为final)。
  • 仅在rowView==null和视图膨胀时设置您的点击监听器,而不是每次通话。
  • 在您的点击处理程序中,在点击的视图上调用getTag以访问ViewHolder。您需要使用的所有内容都应该在视图持有者中。如果没有,请添加它。

如果您需要,请按照此策略准备转换为RecyclerView - 现在可能是个好时机。