0

I'm having a simple ListView filled with some test items:

private ArrayList<NearbyRestaurantListItem> getItems() {
    ArrayList<NearbyRestaurantListItem> items = new ArrayList<>();
    // ..
    items.add( new NearbyRestaurantListItem(null, "Item number " , "seven") );
    items.add( new NearbyRestaurantListItem(null, "Item number " , "eight") );
    items.add( new NearbyRestaurantListItem(null, "Item number " , "nine") );
    items.add( new NearbyRestaurantListItem(null, "Item number " , "ten") );
    // ..
    return items;
}

The thing is that these list items have a toggleable "favorite" button. The strange behavior I am talking about is that if I toggle a favorite button another button from another list item gets toggled too. It appears that the 6th toggle button from the pressed one gets toggled too and I have no idea why. Is it because the OnClickListener* classes are static? NearbyRestaurantListItem is inflated like this:

public View getView(int position, View convertView, ViewGroup parent) {

    NearbyRestaurantListItemViewHolder holder;
    if(convertView == null){
        convertView = mInflater.inflate(R.layout.listview_nearbylist_item, parent, false);
        holder = new NearbyRestaurantListItemViewHolder();
        holder.restaurantThumbnail = (ImageView) convertView.findViewById(R.id.restaurant_thumbnail);
        holder.restaurantName      = (TextView) convertView.findViewById(R.id.restaurant_name);
        holder.restaurantGenre     = (TextView) convertView.findViewById(R.id.restaurant_genre);
        holder.openingHours        = (TextView) convertView.findViewById(R.id.opening_hours);

        convertView.setTag(holder);
    } else {
        holder = (NearbyRestaurantListItemViewHolder) convertView.getTag();
    }

    holder.restaurantThumbnail.setImageDrawable(null);
    holder.restaurantName.setText(items.get(position).getRestaurantName());
    holder.restaurantGenre.setText(items.get(position).getRestaurantGenre());
    holder.openingHours.setText("08:00 - 18:00 Uhr");

    if(holder.restaurantGenre.getText().length() == 0) {
        holder.restaurantGenre.setVisibility(View.GONE);
    }

    ToggleButton favorite = (ToggleButton)convertView.findViewById(R.id.favorite);
    favorite.setOnClickListener(new NearbyRestaurantListFragment.OnClickFavoriteButtonListener(activity));
    favorite.setTag(convertView);

    ImageView map = (ImageView)convertView.findViewById(R.id.map);
    map.setOnClickListener(new NearbyRestaurantListFragment.OnClickMapButtonListener(activity));
    map.setTag(convertView);

    return convertView;
}

I really feel stupid asking this but I can't figure out the problem here.

Stefan Falk
  • 23,898
  • 50
  • 191
  • 378

2 Answers2

0

The issue here is that in Android ListViews, the individual item rows are being recycled, and you're not resetting the state of the favorite button. You should add your favorite button to the holder and change its state appropriately (or reset it to untoggled).

Oleg Vaskevich
  • 12,444
  • 6
  • 63
  • 80
0

I have implemented something similar in this post. Check it out, it is what you need.

Community
  • 1
  • 1
Bojan Kseneman
  • 15,488
  • 2
  • 54
  • 59
  • Is this the way to go? Writing an `interface` in order to have such a callback? Would I let my `Fragment` implement those interfaces instead my Main-Activity if I use a swipe view with multiple fragments? – Stefan Falk Apr 19 '15 at 22:13