Reputation: 16224
I'm changing my adapter code from the basic getView()
to ViewHolder
pattern. My adapter has one TextView
, one ImageView
and one ImageButton
. Everything looks fine but i'm having some problems with the ImageButton
. I'll post both my code (the one with getView()
and the other with ViewHolder
).
The one with getView()
works perfectly, so i'm asking here cause i can't understand where i'm doing wrong in the ViewHolder
's ImageButton
.
Adapter class with 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;
}
}
Adapter class with 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;
}
}
As you can see the code inside onClick()
is the same but with ViewHolder
it doesn't work, can someone explain me why?
P.s. If you need more code or classes tell me and i'll edit my answer.
Upvotes: 1
Views: 956
Reputation: 15379
Follow this strategy to properly use click listeners with the view holder pattern:
getView(...)
call. This will ensure you dont have problems with thinking you have closures (so you dont need position to be declared final
anymore).rowView==null
and the view is inflated, not on every call.getTag
on the view clicked to access the ViewHolder. Everything you need to use should be in the view holder. If not, add it.Follow this strategy will well prepare you to convert to RecyclerView
if you ever need to - maybe now would be a good time.
Upvotes: 4