Imagens de Picasso não estão carregando no Gridview Android

Eu tenho feito um Movie App (trabalho de projeto para aprender android no udacity btw). Eu encontrei alguns problemas, mas resolvi-los seguindo tópicos como estes Não é possível modificar ArrayAdapter em ListView: UnsupportedOperationException

No entanto, embora meu aplicativo não trave, as imagens não estão sendo carregadas e não consigo descobrir por quê. Aqui está o meu código:

Arquivos XMl de layout movies_item.xml

   

fragment_main.xml

    

MovieArrayAdapter.java

  public class MovieArrayAdapter extends ArrayAdapter { private final Context context; private final List movies; public MovieArrayAdapter(Context context,List movies) { super(context,0,movies); this.context = context; this.movies = movies; } /* * Within the getView() method you would inflate an XML based layout and * then set the content of the individual views based on the Java object for this row. * */ @Override public View getView(int position, View convertView, ViewGroup parent) { View rowView = convertView; if(rowView == null) { //Inflate the XML based Layout LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); rowView = inflater.inflate(R.layout.movies_item, parent, false); //Get the ImageView ImageView movieThumbnail = (ImageView) rowView.findViewById(R.id.movies_item_thumbnail); //Load Image into the ImageView Picasso.with(context).load(movies.get(position).getThumbnail()).into(movieThumbnail); Log.v("Populating", movies.get(position).getThumbnail()); } return rowView; } @Override public int getCount() { return super.getCount(); } @Override public int getPosition(Movie item) { return super.getPosition(item); } } MovieFragment.java public class MoviesFragment extends Fragment { private MovieArrayAdapter mMoviesAdapter; public MoviesFragment() { } @Override public void onStart() { super.onStart(); new FetchMoviesTask().execute(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); mMoviesAdapter = new MovieArrayAdapter(getActivity(),new ArrayList()); GridView moviesGridView = (GridView) rootView.findViewById(R.id.movies_gridview); moviesGridView.setAdapter(mMoviesAdapter); return rootView; } public class FetchMoviesTask extends AsyncTask { final String LOG_TAG = this.getClass().getSimpleName(); @Override protected Movie[] doInBackground(String...params) { //Retrieve the Popular Movies Json String String moviesJsonString = getMoviesJsonString(); //Parse the Json String to get important data try { return getPopularMoviesInfo(moviesJsonString); } catch(JSONException e) { Log.e(LOG_TAG,e.getMessage(),e); } return null; } @Override protected void onPostExecute(Movie[] movies) { if(movies != null) { mMoviesAdapter.clear(); mMoviesAdapter.addAll(movies); } } /* * This Function is to retrieve the Popular movies Json String from a WEB API * */ private String getMoviesJsonString() { HttpURLConnection urlConnection = null; BufferedReader bufferedReader = null; String moviesJsonString = null; try { //Set up the URI final String MOVIES_BASE_URL = "http://api.themoviedb.org/3/discover/movie?"; final String SORT_PARAM = "sort_by"; final String API_PARAM ="api_key"; Uri moviesUri = Uri.parse(MOVIES_BASE_URL).buildUpon() .appendQueryParameter(SORT_PARAM, "popularity.desc") .appendQueryParameter(API_PARAM,getString(R.string.movies_api)) .build(); //Open the connection URL url = new URL(moviesUri.toString()); urlConnection = (HttpURLConnection)url.openConnection(); urlConnection.setRequestMethod("GET"); urlConnection.connect(); //Read the input stream into a string InputStream inputStream = urlConnection.getInputStream(); if(inputStream == null) { return null; } bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String line; StringBuffer buffer = new StringBuffer(); while((line = bufferedReader.readLine()) != null) { buffer.append(line + "\n"); } if(buffer.length() == 0){ //Stream was empty return null; } moviesJsonString = buffer.toString(); }catch(IOException e) { Log.e(LOG_TAG,"Error",e); } finally { if (urlConnection != null) { urlConnection.disconnect(); } if(bufferedReader != null) { try { bufferedReader.close(); } catch(IOException e) { Log.e(LOG_TAG, "Error closing stream", e); } } } return moviesJsonString; } /* * This function is to parse the JSON String to retrieve info * */ private Movie[] getPopularMoviesInfo(String jsonString) throws JSONException{ //Base URL of thumbnail final String THUMBNAIL_BASE_URL = " http://image.tmdb.org/t/p/w185"; //The attribute names we are interested in the JSON String final String M_RESULTS = "results"; final String M_THUMBNAIL = "backdrop_path"; final String M_TITLE = "original_title"; final String M_ID = "id"; final String M_SYPNOSIS = "overview"; final String M_USER_RATING = "vote_average"; final String M_RELEASE_DATE = "release_date"; //Convert Json String to Json Object JSONObject moviesJsonObject = new JSONObject(jsonString); //Get the Json Array JSONArray moviesJsonArray = moviesJsonObject.getJSONArray(M_RESULTS); Movie[] movies = new Movie[moviesJsonArray.length()]; for(int i=0;i<moviesJsonArray.length();i++) { JSONObject movie = moviesJsonArray.getJSONObject(i); movies[i] = new Movie(THUMBNAIL_BASE_URL + movie.getString(M_THUMBNAIL), movie.getString(M_TITLE), movie.getString(M_ID), movie.getString(M_SYPNOSIS), movie.getString(M_USER_RATING), movie.getString(M_RELEASE_DATE)); Log.v("Movie",movie.getString(M_TITLE)); } return movies; } } } 

Não há erro, mas as imagens não estão sendo carregadas. Eu tenho procurado em outros tópicos, mas não consigo encontrar a resposta para o meu problema. Muito obrigado.

[ATUALIZADO] Alterou o código de acordo com a discussão abaixo:

 @Override public View getView(int position, View convertView, ViewGroup parent) { if(convertView == null) { //Inflate the XML based Layout LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.movies_item, parent, false); } //Get the ImageView ImageView movieThumbnail = (ImageView) convertView.findViewById(R.id.movies_item_thumbnail); //Load Image into the ImageView Picasso.with(context).load(movies.get(position).getThumbnail()).into(movieThumbnail); Log.v("Populating", movies.get(position).getThumbnail()); return convertView; } 

essa linha:

 //Get the ImageView ImageView movieThumbnail = (ImageView) rowView.findViewById(R.id.movies_item_thumbnail); //Load Image into the ImageView Picasso.with(context).load(movies.get(position).getThumbnail()).into(movieThumbnail); 

vai fora do if(rowView == null) {

Você sempre obterá apenas um convertView null e terá que chamar essas duas linhas enquanto atualiza / preenche seu GridView . No momento, você deve ver sempre a primeira imagem repetidamente. Por favor, não esqueça de adicionar a permissão da Internet ao manifesto