【问题标题】:null value when fetch image from json data using picasso使用毕加索从 json 数据中获取图像时的空值
【发布时间】:2017-11-25 02:41:17
【问题描述】:

我尝试创建一个电影应用程序,因此我创建了 recycleview 以使用带有 api json 数据的网络在 gridlayout 中显示海报 现在该应用程序可以获取电影的名称,并且它的受欢迎程度没有问题,但无法获取海报,当我调试该应用程序时,我发现 onbindviewholder 的海报值为 null 为什么会这样?

这是recycleview的适配器:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> {

    ArrayList<MovieItem> mMoviesItems;
    private Context context;

    public RecyclerViewAdapter() {

    }

    class RecyclerViewHolder extends RecyclerView.ViewHolder {

        public final TextView MoviePopularity;
        public final ImageView MoviePoster;
        public final TextView MovieName;

        public RecyclerViewHolder(View view) {
            super(view);
            MoviePopularity = (TextView)itemView.findViewById(R.id.movie_popularity);
            MoviePoster = (ImageView)itemView.findViewById(R.id.iv_item_movie);
            MovieName = (TextView)itemView.findViewById(R.id.movie_name);
        }
    }

    @Override
    public RecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        context = viewGroup.getContext();
        int layoutIdForListItem = R.layout.movie_list_item;
        LayoutInflater inflater = LayoutInflater.from(context);
        boolean shouldAttachToParentImmediately = false;

        View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
        return new RecyclerViewHolder(view);

    }

    @Override
    public void onBindViewHolder(RecyclerViewHolder holder, int position) {
        holder.MoviePopularity.setText(String.valueOf(mMoviesItems.get(position).getPopularity()));
        Picasso.with(this.context).load(mMoviesItems.get(position).getPhoto()).into(holder.MoviePoster);
        holder.MovieName.setText(String.valueOf(mMoviesItems.get(position).getName()));
    }


    @Override
    public int getItemCount() {
        if (null == mMoviesItems)
            return 0;
        else {
            return mMoviesItems.size();
        }
    }

    public void setMovieData(ArrayList<MovieItem> movieData) {
        mMoviesItems = movieData;
        notifyDataSetChanged();
    }

}

这是自定义类:

public class MovieItem {
    private double popularity;
    private String photo;
    private String name;

    public MovieItem(double popularity, String poster_path, String original_title) {
        this.popularity = popularity;
        this.photo = poster_path;
        this.name = original_title;
    }

    public double getPopularity() { return popularity; }
    public String getPhoto() { return photo; }
    public String getName() { return name; }
}

这是 json 类: 公共最终类 OpenMovieJsonUtils {

    public static ArrayList<MovieItem> getSimpleMovieStringsFromJson(Context context, String moviesJsonString)
            throws JSONException {

        final String RESULTS = "results";
        final String POPULARITY = "popularity";
        final String POSTER_PATH = "poster_path";
        final String ORIGINAL_TITLE = "original_title";

        ArrayList<MovieItem> parsedMovieData = new ArrayList<MovieItem>();

        JSONObject moviesObject = new JSONObject(moviesJsonString);
        JSONArray moviesArray = moviesObject.getJSONArray(RESULTS);

        for (int i = 0; i < moviesArray.length(); i++) {
            double popularity;
            String poster_path;
            String original_title;

            moviesObject = moviesArray.getJSONObject(i);

            popularity = moviesObject.getDouble(POPULARITY);
            poster_path = moviesObject.getString(POSTER_PATH);
            original_title = moviesObject.getString(ORIGINAL_TITLE);

            parsedMovieData.add(new MovieItem(popularity, poster_path, original_title));

        }

        return parsedMovieData;
    }
}

这是网络类:

public final class NetworkUtils {

    private static final String TAG = NetworkUtils.class.getSimpleName();

    private static final String MOVIES_BASE_URL = "https://api.themoviedb.org/3/movie/";
    private static final String MOVIES_URL  = MOVIES_BASE_URL;
    private static final String apiKey = "36666cbb5d7e20041e705d1b2c4e7a79";

    final static String API_PARAM = "api_key";

    public static URL buildUrl(String MoviesQuery) {
        Uri builtUri = Uri.parse(MOVIES_URL).buildUpon()
                .appendPath(MoviesQuery)
                .appendQueryParameter(API_PARAM, apiKey)
                .build();

        URL url = null;
        try {
            url = new URL(builtUri.toString());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        Log.v(TAG, "Built URI " + url);
        return url;
    }

    public static String getResponseFromHttpUrl(URL url) throws IOException {
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        try {
            InputStream in = urlConnection.getInputStream();

            Scanner scanner = new Scanner(in);
            scanner.useDelimiter("\\A");

            boolean hasInput = scanner.hasNext();
            if (hasInput) {
                return scanner.next();
            } else {
                return null;
            }
        } finally {
            urlConnection.disconnect();
        }
    }
}

图像有什么问题,所以我将它们的值设为 null 而不是电影作品的受欢迎程度和名称,而不是 null

【问题讨论】:

    标签: java android json


    【解决方案1】:

    您的问题不完整,没有详细说明您从何处获得 API 响应。

    我可以回答这个问题,因为我刚刚在 Udacity 的 Android Developer Nanodegree 中完成了这个项目。

    希望您从 TMDB 获取电影详细信息。

    您应该仔细阅读项目实施指南,其中说

    您需要在此相对路径之前附加一个基本路径,以构建完整的 url,您需要使用 Picasso 获取图像

    以下代码将对您有所帮助 -

    public class MovieItem {
        private double popularity;
        private String photo;
        private String name;
    
        public MovieItem(double popularity, String poster_path, String original_title) {
            this.popularity = popularity;
            this.photo = poster_path;
            this.name = original_title;
        }
    
        public double getPopularity() { return popularity; }
        public String getPhoto() { return photo; }
        public String getName() { return name; }
    
        public Uri getFullPosterPath() {
            return Uri.parse("http://image.tmdb.org/t/p/")
                    .buildUpon()
                    .appendPath("w185")
                    .appendEncodedPath(getPhoto())
                    .build();
        }
    }
    

    并在适配器中进行此更改 -

    @Override
        public void onBindViewHolder(RecyclerViewHolder holder, int position) {
            holder.MoviePopularity.setText(String.valueOf(mMoviesItems.get(position).getPopularity()));
            Picasso.with(this.context).load(mMoviesItems.get(position).getFullPosterPath()).into(holder.MoviePoster);
            holder.MovieName.setText(String.valueOf(mMoviesItems.get(position).getName()));
        }
    

    【讨论】:

    • 对不起,因为我的问题不清楚,现在我编辑问题并在最后添加你可以看到的网络类,然后写我使用 TMDB,我是纳米学位的学生udacity 我会做你在这里写的更改并返回给你
    • 非常感谢,我试过了,现在效果很好,你拯救了我的一天
    猜你喜欢
    • 2018-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-02
    • 2020-06-27
    • 2016-12-24
    • 2016-11-14
    • 1970-01-01
    • 2021-10-01
    相关资源
    最近更新 更多