Search code examples
androidlistviewandroid-listviewandroid-adapterandroid-adapterview

What are the conditions under which an adapter doesn't update attached view


I am using this library to create swipe-able cards : https://github.com/Diolor/Swipecards

The view which makes the swipe-able cards control, gets attached to an adapter and sources it's drawing from it.

In my implementation, every card has a button, and when it is clicked, something in the source array changes, for which I want to refresh the whole card list. I call notifyDataSetChanged() on the associated adapter, but the getView() never gets called in the adapter to see any updates.

What's strange is that the same adapter works perfectly with a ListView

Is there any specific requirement either in the adapter's side or in the view itself which is required for the proper functioning of notifyDataSetChanged?

My Code:
(Please ignore the absence of ViewHolder pattern and the presence of click receivers inside the adapter. Code quality is the least thing I can be concerned about right now when a crucial functionality isn't working)

Adapter (using Array Adapter)

public class TourCardAdapter extends ArrayAdapter<TourCardBean> implements View.OnClickListener {

    Context context;
    ToursFragment.ToursControlsClickListener clickListener;

    public TourCardAdapter(Context context, ArrayList<TourCardBean> tourCardsArr, ToursFragment.ToursControlsClickListener clickListener) {
        super(context, 0, tourCardsArr);
        this.context = context;
        this.clickListener = clickListener;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View rowView = convertView;
        ViewHolder viewHolder;
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        TourCardBean tourCard = getItem(position);

        rowView = inflater.inflate(R.layout.card_tour, parent, false);


        viewHolder = new ViewHolder();

        viewHolder.title = (TextView) rowView
                .findViewById(R.id.title);
        viewHolder.detail = (TextView) rowView
                .findViewById(R.id.detail);
        viewHolder.likeCount = (TextView) rowView
                .findViewById(R.id.likeCount);
        viewHolder.image = (ImageView) rowView
                .findViewById(R.id.cardLocationImage);
        viewHolder.likeButton = (ImageView) rowView
                .findViewById(R.id.cardLikeImage);
        viewHolder.shareButton = (ImageView) rowView
                .findViewById(R.id.cardShareImage);

        viewHolder.likeButton.setOnClickListener(this);
        viewHolder.shareButton.setOnClickListener(this);

        viewHolder.title.setText(tourCard.getTitle());
        viewHolder.detail.setText(tourCard.getDetails());
        viewHolder.likeCount.setText("" + tourCard.getLikeCount());
        viewHolder.likeButton.setTag(tourCard.getId());
        viewHolder.shareButton.setTag(tourCard.getId());

        return rowView;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.cardLikeImage:
                clickListener.onLikeClick((int) v.getTag());
                break;
            case R.id.cardShareImage:
                clickListener.onShareClick((int) v.getTag());
                break;
        }
    }


    /**
     * View Holder for ListView
     *
     * @author Aman Alam
     */
    class ViewHolder {
        public ImageView image;
        public ImageView likeButton;
        public ImageView shareButton;
        public TextView title;
        public TextView detail;
        public TextView likeCount;
    }
}

Solution

  • Based on some of the issues logged against the Swipecards library, it appears that it may have bugs that prevent it from updating the views on notifyDataSetChanged(). This one has a couple of workarounds that might work for you. Specifically, flingContainer.removeAllViewsInLayout().