Search code examples
androidandroid-recyclerviewthumbnailsandroid-glide

Thumbnail stays blank in RecyclerView (Android). Am I using Glide correctly?


I am working on an Android app that displays a list of books that match a search term. I am using the Google Books API. From the API I get a list of the following items: title, author, publication date and URI for a small thumbnail to display.

I am able to display the information in the RecyclerView except the thumbnail. For that I am trying to use the Glide library. It always stays blank and if I use the placeholder option it always displays the placeholder. (I have added the dependencies in the Gradle file also).

implementation 'com.github.bumptech.glide:glide:4.11.0'
  annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'

I have tried debugging and indeed the variable mThumbnail is not empty and has a valid address. Is this the correct way of using Glide for thumbnails?

I'll post below my layout for the RecyclerView item and adapter code also.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:paddingTop="10dp"
    android:paddingBottom="10dp"
    android:paddingEnd="16dp"
    android:paddingLeft="16dp"
    android:paddingStart="16dp"
    android:paddingRight="16dp"
    android:orientation="horizontal">

    <ImageView
        android:id="@+id/book_thumbnail"
        android:layout_width="100dp"
        android:layout_height="150dp"
        <!--app:layout_constraintDimensionRatio = "4:5.5"-->
         />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical"
        android:visibility="visible">

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:text="Le petit prince" />

        <TextView
            android:id="@+id/authors"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:text="Antoine-Saint Exupery" />

        <TextView
            android:id="@+id/publishedDate"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:text="1943" />

    </LinearLayout>
    
</LinearLayout>

And the adapter code:

package com.example.booksearch;

import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * Adapter used for RecyclerView
 */
public class BookListAdapter extends RecyclerView.Adapter<BookListAdapter.BookViewHolder>{

    private LayoutInflater mInflater;
    private final List<Book> mBookList;
    Context context;

    /**
     * BookListAdapter constructor.
     * @param context Takes context of applications
     * @param bookList A list of books.
     */
    public BookListAdapter(Context context, ArrayList<Book> bookList){
        mInflater = LayoutInflater.from(context);
        this.mBookList = bookList;
        this.context = context;
    }

    /**
     * Empties adapter.
     */
    public void clear(){
        mBookList.clear();
    }

    /**
     * Adds all books to adapter.
     * @param books List of books to add.
     */
    public void addAll(ArrayList<Book> books){
        mBookList.addAll(books);
    }

    /**
     * Used on creating of BookViewHolder
     * @param parent BookViewHolder
     * @param viewType
     * @return A BookViewHolder object
     */
    @NonNull
    @Override
    public BookViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View mItemView = mInflater.inflate(R.layout.book_item,parent, false);
        return new BookViewHolder(mItemView, this);
    }

    /**
     * Binds (sets content of ViewHolder)
     * @param holder Holder to work on
     * @param position Position of the book that belongs to the ViewHolder
     */
    @Override
    public void onBindViewHolder(@NonNull BookListAdapter.BookViewHolder holder, int position) {
        String mTitle = mBookList.get(position).getTitle();
        String mAuthor = mBookList.get(position).getAuthor();
        String mPublishedDate = mBookList.get(position).getPublishedYear();
        Uri mThumbnailUri = mBookList.get(position).getThumbnailUri();

        holder.titleView.setText(mTitle);
        holder.authorView.setText(mAuthor);
        holder.publishedYearView.setText(mPublishedDate);

        if (!mThumbnailUri.toString().isEmpty()){
            Glide.with(context)
                    .load(mThumbnailUri.toString())
                    .override(100,200)
                    //.placeholder(R.drawable.ic_baseline_book_24)
                    .into(holder.thumbnailView);
        } else {
            Glide.with(context)
                    .load(R.drawable.ic_baseline_book_24)
                    .into(holder.thumbnailView);
            holder.thumbnailView.setImageAlpha(50);
        }


    }

    /**
     * Returns size of book list.
     * @return An integer with size of the list.
     */
    @Override
    public int getItemCount() {
        return mBookList.size();
    }

    /**
     * Inner class of BookListAdapter, for ViewHolder of book object.
     */
    class BookViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
        public final TextView titleView;
        public final TextView authorView;
        public final TextView publishedYearView;
        public final ImageView thumbnailView;
        final BookListAdapter mAdapter;

        /**
         * Constructor of BookViewHolder object.
         * @param itemView The itemView for one book object.
         * @param adapter The adapter that is used for book objects.
         */
        public BookViewHolder(View itemView, BookListAdapter adapter){
            super(itemView);
            titleView = itemView.findViewById(R.id.title);
            authorView = itemView.findViewById(R.id.authors);
            publishedYearView = itemView.findViewById(R.id.publishedDate);
            thumbnailView = itemView.findViewById(R.id.book_thumbnail);
            //thumbnailView.setScaleType(ImageView.ScaleType.CENTER);
            this.mAdapter = adapter;
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {

        }
    }


}


Solution

  • i dont have enough reputation to comment yet, so can i ask for your api result? and Log of the thumbnail?

    i'm gonna assume for now your json or whatever your api result, return for thumbnail is as String, if it is a String then you just need to load it to the glide, but of course refactor your model to String first so your code for

    Uri mThumbnailUri = mBookList.get(position).getThumbnailUri()
    

    become

    String mThumbnail = mBookList.get(position).getThumbnail()
    
    Glide.with(context).load(mThumbnail)
    
    

    because glide can take String as it's parameter