Bharat
Bharat

Reputation: 421

Picasso with android recycler view not loading images

i am using volley to make REST API requests to tmdb database for loading information about movies. The recycler view should display thumbnail image posters. But it is not displaying anything. i am using picasso library to load images. the image links are constructed fine, which i have checked with log statement

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.android.moviesapp.MainActivity">
    <android.support.v7.widget.RecyclerView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/movierecyclerview">
    </android.support.v7.widget.RecyclerView>
</RelativeLayout>

list_item_layout.xml

<?xml version="1.0" encoding="utf-8"?>
   <android.support.v7.widget.CardView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/movie_poster_cardview">
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/movie_poster_imageview"/>
    </android.support.v7.widget.CardView>

MainActivity

package com.example.android.moviesapp;

import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.squareup.picasso.Callback;
import com.squareup.picasso.Picasso;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;


public class MainActivity extends AppCompatActivity {

    private ArrayList<HashMap<String, String>> movies = new ArrayList<>();
    private ArrayList<String> moviePosters = new ArrayList<>();

    final static String POSTER_PATH = "poster_path";
    final static String TITLE = "title";
    final static String VOTE_COUNT = "vote_count";
    final static String VOTE_AVERAGE = "vote_average";
    final static String OVERVIEW = "overview";
    final static String RELEASE_DATE ="release_date";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final MoviesAdapter adapter = new MoviesAdapter(getApplicationContext(), moviePosters);

        RecyclerView moviesRecyclerView = (RecyclerView) findViewById(R.id.movierecyclerview);
        moviesRecyclerView.setAdapter(adapter);
        moviesRecyclerView.setLayoutManager(new GridLayoutManager(getApplicationContext(), 2));

       try {

           final String BASE_URL =
                   "https://api.themoviedb.org/3/movie/";
           final String movieOrder = "popular";
           final String APPID = /* API KEY HERE */;

           Uri builtUri = Uri.parse(BASE_URL).buildUpon().appendPath(movieOrder).appendQueryParameter("api_key",APPID).build();

           URL url = new URL(builtUri.toString());

            JsonObjectRequest movieRequest = new JsonObjectRequest(Request.Method.GET, url.toString(), null, new Response.Listener<JSONObject>() {

                @Override
                public void onResponse(JSONObject response) {
                    try {


                        JSONArray results = response.getJSONArray("results");

                        Log.d ("DEBUG", response.toString());
                        for (int i = 0; i < results.length(); i++) {

                            JSONObject movieJSON = results.getJSONObject(i);
                            HashMap<String, String> movie = new HashMap<>();
                            movie.put(POSTER_PATH,movieJSON.getString(POSTER_PATH));
                            movie.put(TITLE,movieJSON.getString(TITLE));
                            movie.put(VOTE_COUNT,movieJSON.getString(VOTE_COUNT));
                            movie.put(VOTE_AVERAGE, movieJSON.getString(VOTE_AVERAGE));
                            movie.put(OVERVIEW, movieJSON.getString(OVERVIEW));
                            movie.put(RELEASE_DATE, movieJSON.getString(RELEASE_DATE));
                            movies.add(movie);
                        }
                    }
                    catch (JSONException e) {
                        Log.d ("DEBUG", "JSON exception");
                    }

                    for (HashMap<String, String> movie:movies) {
                        moviePosters.add(movie.get(POSTER_PATH));
                        adapter.notifyDataSetChanged();
                    }
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.d ("DEBUG","Network Error");
                }
            });

           RequestQueue mRequestQueue = MovieDataLoader.getSingletonInstance(this.getApplicationContext()).getRequestQueue();


            mRequestQueue.add(movieRequest);
        }
        catch (MalformedURLException e) {
            Log.d("DEBUG", "url not formed correctly");
        }



    }

    public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.MoviesViewHolder> {

        private ArrayList<String> movies;
        private Context mContext;

        public class MoviesViewHolder extends RecyclerView.ViewHolder {

            public ImageView mImageView;

            public MoviesViewHolder (View itemView) {
                super(itemView);
                mImageView = (ImageView) itemView.findViewById(R.id.movie_poster_imageview);
            }

        }

        public MoviesAdapter(Context context, ArrayList<String> movies) {
            this.movies = movies;
            mContext = context;
        }

        @Override
        public MoviesViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            View moviesView = inflater.inflate(R.layout.list_item_layout,parent,false);
            return new MoviesViewHolder(moviesView);

        }

        @Override
        public int getItemCount() {
            return movies.size();
        }

        @Override
        public void onBindViewHolder(MoviesViewHolder holder, int position) {
            String moviePosterPath = movies.get(position);
            final String BASE_URL = " http://image.tmdb.org/t/p/";
            final String IMAGE_SIZE = "w185";

            Uri posterPath = Uri.parse(BASE_URL).buildUpon().appendPath(IMAGE_SIZE).appendEncodedPath(moviePosterPath).build();
            Log.d("DEBUG",posterPath.toString());
            picasso.with(mContext).load(posterPath.toString()).into(holder.mImageView);

        }
    }
}

MovieDataLoader

package com.example.android.moviesapp;

import android.content.Context;
import android.graphics.Bitmap;
import android.util.LruCache;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;
import com.android.volley.toolbox.Volley;

public class MovieDataLoader {

    private static MovieDataLoader mSingletonInstance;
    private RequestQueue mRequestQueue;
    private static Context mCtx;

    private MovieDataLoader(Context ctx) {
        mCtx = ctx;
        mRequestQueue = getRequestQueue();

    }

    public static synchronized MovieDataLoader getSingletonInstance(Context ctx) {
        if (mSingletonInstance == null) {
            mSingletonInstance = new MovieDataLoader(ctx);
        }
        return mSingletonInstance;
    }

    public RequestQueue getRequestQueue() {
        if(mRequestQueue == null) {

            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
        }
        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {
        getRequestQueue().add(req);
    }


}

Upvotes: 1

Views: 2969

Answers (1)

Gurupad Mamadapur
Gurupad Mamadapur

Reputation: 989

I'm going to point out where the bugs are lying and how you can find them.

  • Read the logs carefully and you'll see an error related to permissions
  • Inspect the code in onBindViewHolder by adding break points and running in debug mode. There is a problem with some constant.
  • Check your activity_main.xml, especially the attributes of RecyclerView.

Proceed ahead only if you couldn't find those.


  • You need to add uses - INTERNET permission in the manifest.xml.
  • There is an extra leading space in the BASE_URL. Remove it.
  • Change wrap_content to match_parent.

Also, you shouldn't add listeners in that way. You've should implement them in the MainActivity.class itself, so that you need not declare adapter variable as final. Check the pull request here.

Upvotes: 2

Related Questions