Reputation: 421
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
Reputation: 989
I'm going to point out where the bugs are lying and how you can find them.
onBindViewHolder
by adding break points and running in debug mode. There is a problem with some constant.activity_main.xml
, especially the attributes of RecyclerView
.Proceed ahead only if you couldn't find those.
uses - INTERNET
permission in the manifest.xml.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