我将适配器代码从基本的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则不起作用,有人可以解释一下为什么吗?
P.s.如果您需要更多代码或课程,请告诉我,我将编辑答案。

最佳答案

请按照以下策略正确使用带有视图持有人模式的点击侦听器:


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


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

关于android - ViewHolder模式的“按一下”问题,但getView模式没有,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28999814/

10-12 00:34
查看更多