Java – picasso images are not loaded in Gridview Android

picasso images are not loaded in Gridview Android… here is a solution to the problem.

picasso images are not loaded in Gridview Android

I’ve been making a movie app (by the way, project work on learning android on udacity). I ran into some issues, but they were solved with the following thread Unable to modify ArrayAdapter in ListView: UnsupportedOperationException

However, while my app didn’t crash, the images didn’t load, and I don’t know why. Here is my code :

Layout XMl file movies_item.xml

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id = "@+id/movies_item_thumbnail"
    >
</ImageView>

fragment _main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.example.cindy.popularmovies.MoviesFragment">

<GridView
        android:id="@+id/movies_gridview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:numColumns="auto_fit"
        android:gravity="center"
        />

</FrameLayout>

MovieArrayAdapter.java

    public class MovieArrayAdapter extends ArrayAdapter<Movie> {
        private final Context context;
        private final List<Movie> movies;

public MovieArrayAdapter(Context context,List<Movie> 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<Movie>());

GridView moviesGridView = (GridView) rootView.findViewById(R.id.movies_gridview);
        moviesGridView.setAdapter(mMoviesAdapter);

return rootView;
    }

public class FetchMoviesTask extends AsyncTask<String,Void,Movie[]> {

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;

}
    }
}

There are no errors, but the picture does not load. I’ve been looking for other threads but can’t find an answer to my question. Thank you so much.

[Updated] Changed the code based on the discussion below:

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

Solution

That line:

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

Jump out if(rowView == null) {

You will always only get a null convertView, both lines that you have to call when updating/populating your GridView. Currently, you should always see the first picture over and over again. Don’t forget to add internet permissions to the list

Related Problems and Solutions