1

アダプタ コードを基本getView()からViewHolderパターンに変更しています。私のアダプターには one TextView、 one ImageView、 oneがありImageButtonます。すべて問題ないように見えますが、ImageButton. 両方のコードを投稿します (1 つはgetView()で、もう1 つは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 に答える