Edgar.A
Edgar.A

Reputation: 1383

Xamarin.Droid RecyclerView shows image only once

I'm trying to implement RecyclerView with CardView, cards are just imageviews with textview on top of it. At first everything works as intended, but if you for example scroll down, and then back up in recyclerView then imageViews will be empty, textviews are fine.

gif of what happens

gif of what happens

Adapter:

    public class NewsCardAdapter : RecyclerView.Adapter
{
    private List<RSSItem> items;

    public NewsCardAdapter()
    {
        HasStableIds = true;
    }

    public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
    {
        var view = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.NewsItem, parent, false);
        NewsViewHolder viewHolder = new NewsViewHolder(view);
        return viewHolder;
    }

    public override long GetItemId(int position)
    {
        return items[position].Id;
    }

    public override async void OnBindViewHolder(RecyclerView.ViewHolder viewHolder, int position)
    {
        var item = items[position];
        var holder = viewHolder as NewsViewHolder;
        if (item.ThumbNail != null)
        {
            holder.ImgThumbnail.SetImageBitmap(await BitmapFactory.DecodeStreamAsync(item.ThumbNail));
        }
        else
        {
            // Place holder in case item doesn't have thumbnail
            holder.ImgThumbnail.SetImageResource(Resource.Drawable.Icon);
        }
        holder.Title.Text = item.Title;
    }

    public override int ItemCount => items.Count;

    public List<RSSItem> Items
    {
        get { return items; }
        set { items = value; }
    }
}

public class NewsViewHolder : RecyclerView.ViewHolder
{
    private ImageView imgThumbnail;
    private TextView title;

    public NewsViewHolder(View itemView) : base(itemView)
    {
        imgThumbnail = itemView.FindViewById<ImageView>(Resource.Id.img_thumbnail);
        title = itemView.FindViewById<TextView>(Resource.Id.news_title);
    }

    public ImageView ImgThumbnail
    {
        get { return imgThumbnail; }
        set { imgThumbnail = value; }
    }

    public TextView Title
    {
        get { return title; }
        set { title = value; }
    }
}

Model (RSSItem) :

 public class RSSItem : INotifyPropertyChanged
{
    [PrimaryKey, AutoIncrement]
    public long Id { get; set; }
    public string Title { get; set; }
    private Stream thumbnail;

    [Ignore]
    public Stream ThumbNail
    {
        get { return thumbnail; }
        set
        {
            thumbnail = value;
            OnPropertyChanged();
        }
    }
    // ...
}

My guess - it has something to do with assigning imageView source to bitmap decoded from stream and not storing bitmap itself in model. However I cannot do that since System.Drawable is not part of PCL.

Upvotes: 0

Views: 219

Answers (2)

Miha Markic
Miha Markic

Reputation: 3240

Try to positioning Stream to start before decoding, like Stream.Position = 0; Also, not sure what your stream is, you could use MemoryStreams to cache image at PCL level, or cache images at UI level (by storing BitmapFactory.DecodeStreamAsync results).

Upvotes: 1

jzeferino
jzeferino

Reputation: 7850

I suggest you to use Picasso Library to retrieve images. Its more performant (mainly in memory) and will sove your problem.

Upvotes: 0

Related Questions