1

我正在将我的适配器代码从基本getView()更改为ViewHolder模式。我的适配器有一个TextView,一个ImageView和一个ImageButton。一切看起来都很好,但我遇到了一些问题ImageButton。我将发布我的两个代码(一个带有getView(),另一个带有ViewHolder)。一个getView()完美的作品,所以我在这里问,因为我不明白我在哪里做错了ViewHolderImageButton

带有 getView() 的适配器类

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

带有 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;
    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()是一样的,但ViewHolder它不起作用,有人能解释一下为什么吗?Ps 如果您需要更多代码或课程,请告诉我,我会编辑我的答案。

4

1 回答 1

4

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

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

RecyclerView如果您需要,遵循此策略将为您做好转换的准备——也许现在是个好时机。

于 2015-03-12T03:11:59.917 回答