使用android Recycler视图的毕加索未加载图片

时间:2017-01-30 16:19:34

标签: android android-recyclerview picasso

我正在使用volley对tmdb数据库发出REST API请求以加载有关电影的信息。回收者视图应显示缩略图图像海报。但它没有显示任何东西。我正在使用毕加索库来加载图像。图像链接构造正常,我已使用日志语句检查

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);
    }


}

1 个答案:

答案 0 :(得分:2)

我要指出错误所在的位置以及如何找到它们。

  • 仔细阅读日志,您将看到与权限相关的错误
  • 通过添加断点并在debug mode中运行来检查onBindViewHolder中的代码。某些常数存在问题。
  • 检查您的activity_main.xml,尤其是RecyclerView
  • 的属性

只有在找不到这些内容时才继续。

  • 您需要在manifest.xml中添加uses - INTERNET权限。
  • BASE_URL中有一个额外的前导空格。删除它。
  • wrap_content更改为match_parent

另外,你不应该以这种方式添加听众。您应该在MainActivity.class中实现它们,这样您就不需要将adapter变量声明为final。检查拉取请求here