使用picasso 2.5.2

时间:2015-12-21 17:30:31

标签: android gridview picasso

目前我正在开发udacity的热门电影应用,并坚持加载MovieDb api中的图像。我也参考了这个帖子Picasso Images are not loading in Gridview Android,但没有用。

这是我的片段文件:

package com.akshitjain.popularmovies;

import android.net.Uri;
import android.os.AsyncTask;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;

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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * A placeholder fragment containing a simple view.
*/
public class MainActivityFragment extends Fragment {
ImageAdapter mMoviesAdapter;

public MainActivityFragment() {
}

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    setHasOptionsMenu(true);
    super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    final View rootView = inflater.inflate(R.layout.fragment_main, container, false);
    GridView gridview = (GridView) rootView.findViewById(R.id.grid_view_movies);
    mMoviesAdapter = new ImageAdapter(getActivity());
    gridview.setAdapter(mMoviesAdapter);

    gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v,
                                int position, long id) {
            Toast.makeText(getActivity(), "" + position,
                    Toast.LENGTH_SHORT).show();
        }
    });
    return rootView;
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.menu_mainfragment,menu);
    super.onCreateOptionsMenu(menu, inflater);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if(id == R.id.action_refresh){
        String sortOrder = "popularity.desc";
        new FetchMoviesTask().execute(sortOrder);
        return true;
    }
    return super.onOptionsItemSelected(item);
}

public class FetchMoviesTask extends AsyncTask<String, Void, String[]> {
    private final String LOG_TAG = FetchMoviesTask.class.getSimpleName();

    private String[] getMoviesDataFromJson(String moviesJsonStr)
            throws JSONException {
        final String TMDB_RESULTS = "results";
        final String TMDB_POSTER = "poster_path";

        JSONObject moviesJson = new JSONObject(moviesJsonStr);
        JSONArray moviesArray = moviesJson.getJSONArray(TMDB_RESULTS);

        String[] resultStrs = new String[moviesArray.length()];
        for(int i=0;i<moviesArray.length();++i) {
            JSONObject movieObject = moviesArray.getJSONObject(i);
            resultStrs[i] = movieObject.getString(TMDB_POSTER);
        }
        return resultStrs;
    }

    @Override
    protected String[] doInBackground(String... params) {
        // These two need to be declared outside the try/catch
        // so that they can be closed in the finally block.
        HttpURLConnection urlConnection = null;
        BufferedReader reader = null;

        // Will contain the raw JSON response as a string.
        String moviesJsonStr;

        String apiKey = BuildConfig.THE_MOVIE_DB_API_KEY;

        try {
            // Construct the URL for the TheMovieDb query
            // Possible parameters are available at TheMovieDb API page
            final String MOVIES_BASE_URL = "http://api.themoviedb.org/3/discover/movie?";
            final String SORT_PARAM = "sort_by";
            final String API_KEY = "api_key";

            Uri builtUri = Uri.parse(MOVIES_BASE_URL).buildUpon()
                    .appendQueryParameter(SORT_PARAM,params[0])
                    .appendQueryParameter(API_KEY,apiKey)
                    .build();
            URL url = new URL(builtUri.toString());
            Log.v(LOG_TAG,"BuiltUri: " + builtUri.toString());

            // Create the request to TheMovieDb, and open the connection
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();

            // Read the input stream into a String
            InputStream inputStream = urlConnection.getInputStream();
            StringBuilder buffer = new StringBuilder();
            if (inputStream == null) {
                // Nothing to do.
                return null;
            }
            reader = new BufferedReader(new InputStreamReader(inputStream));

            String line;
            while ((line = reader.readLine()) != null) {
                // Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
                // But it does make debugging a *lot* easier if you print out the completed
                // buffer for debugging.
                buffer.append(line).append("\n");
            }

            if (buffer.length() == 0) {
                // Stream was empty.  No point in parsing.
                 return null;
            }
            moviesJsonStr = buffer.toString();
            Log.v(LOG_TAG,"Movies Json String: " + moviesJsonStr);
        } catch (IOException e) {
            Log.e("MainActivityFragment", "Error ", e);
            // If the code didn't successfully get the weather data, there's no point in attempting
            // to parse it.
            return null;
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (final IOException e) {
                    Log.e("MainActivityFragment", "Error closing stream", e);
                }
            }
        }

        try{
            return getMoviesDataFromJson(moviesJsonStr);
        }catch (JSONException e){
            Log.e(LOG_TAG,e.getMessage(),e);
            e.printStackTrace();
        }

        return null;
    }

    @Override
    protected void onPostExecute(String[] strings) {
        if(strings != null){
            mMoviesAdapter.clear();
            for(String moviesStr:strings){
                mMoviesAdapter.add(moviesStr);
            }
        }
        mMoviesAdapter.notifyDataSetChanged();
        super.onPostExecute(strings);
    }
}
}

这是我的自定义适配器文件:

package com.akshitjain.popularmovies;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;

import com.squareup.picasso.Picasso;

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


public class ImageAdapter extends BaseAdapter {
private final String LOG_TAG = ImageAdapter.class.getSimpleName();

private Context mContext;
List<String> list = new ArrayList<>();

public ImageAdapter(Context c) {
    this.mContext = c;
}

@Override
public int getCount() {
    return list.size();
}

@Override
public Object getItem(int position) {
    return list.get(position);
}

@Override
public long getItemId(int position) {
    return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = LayoutInflater.from(mContext).inflate(R.layout.grid_item_movies, parent, false);
    }

    final String POSTER_BASE_URL = " http://image.tmdb.org/t/p/";
    final String POSTER_SIZE = "w185";

    ImageView moviePoster = (ImageView) convertView.findViewById(R.id.grid_item_movie_image);
    final String POSTER_FINAL_URL = POSTER_BASE_URL + POSTER_SIZE + list.get(position);
    Log.v(LOG_TAG,"Poster Urls: " + POSTER_FINAL_URL);
    Picasso.with(mContext).load(POSTER_FINAL_URL).into(moviePoster);

    return convertView;
}

public void add(String s) {
    list.add(s);
}

public void clear() {
    list.clear();
}

}

代码中没有错误。应用成功运行。但图片没有加载。

1 个答案:

答案 0 :(得分:1)

final String POSTER_BASE_URL = " http://image.tmdb.org/t/p/";

字符串开头的空格是个问题。毕加索将尝试加载前面有空格的网址。     因此String.trim()将从字符串的开头和结尾删除空格。

Picasso.with(mContext).load(POSTER_FINAL_URL.trim()).into(moviePoster)