Search code examples
javaandroidgridviewpicasso

Populate a gridview using Picasso in android


I am trying to populate my grid view with the poster images returned from the movie db. I step through and do not encounter and error but nothing is displayed. Here is my code any help would be appreciated. I think the issue is with the adapter but i have debugged this and the grid view ends up with the correct number of children.

public class MainActivity extends AppCompatActivity {

private GridView mMoviesGrid;
private ListAdapter mMoviesAdapter;
public ArrayList<String> mPosterMoviePaths;
String mMovieJsonStr = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mMoviesGrid = (GridView) findViewById(R.id.movie_list_grid);

    new FetchMovieData().execute();

    if(mMovieJsonStr != null){
        mPosterMoviePaths =  MovieDataParser.getMoviePosterPaths(mMovieJsonStr);
    }

    mMoviesAdapter = new MovieAdapter(this, mPosterMoviePaths);
    mMoviesGrid.setAdapter(mMoviesAdapter);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

private class MovieAdapter extends ArrayAdapter {
    private Context mContext;
    private ArrayList<String> mItems;

    public MovieAdapter(Context context, ArrayList<String> objects) {
        super(context, R.layout.movie_grid_item,objects);
        this.mContext = context;
        this.mItems = objects;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent){

        //if the view is null than inflate it otherwise just fill the list with
        if(convertView == null){
            //inflate the layout
            LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
            convertView = inflater.inflate(R.layout.movie_grid_item, parent, false);
        }
        ImageView image =(ImageView) convertView.findViewById(R.id.movie_image);
        Picasso.with(mContext).load(mItems.get(position)).into(image);
        return  convertView;
    }
}

public class FetchMovieData extends AsyncTask <String, Void, Void> {

    @Override
    protected Void 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;

        try {
            // Construct the URL for the OpenWeatherMap query
            // Possible parameters are available at OWM's forecast API page, at
            // http://openweathermap.org/API#forecast
            URL url = new URL(getString(R.string.picasso_url_popular_movies));

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

            // Read the input stream into a String
            InputStream inputStream = urlConnection.getInputStream();
            StringBuffer buffer = new StringBuffer();
            if (inputStream == null) {
                // Nothing to do.
                mMovieJsonStr = 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 + "\n");
            }

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

        return null;
    }

}

}


Solution

  • The problem is that you call AsyncTask in your onCreate Method and below that you are populating your gridView so, AsyncTask Needs time to get the json from the server through internet, but you are not giving it time.So when you populate your gridview and that time you do not have the image url that's why picasso is not able to load the image.

    remove below lines from onCreate

    if(mMovieJsonStr != null){
        mPosterMoviePaths =  MovieDataParser.getMoviePosterPaths(mMovieJsonStr);
    }
    mMoviesAdapter = new MovieAdapter(this, mPosterMoviePaths);
    mMoviesGrid.setAdapter(mMoviesAdapter);
    

    write them in onPostExecute in AsyncTask

    @Override
    protected void onPostExecute(String result) {
       if(mMovieJsonStr != null){
        mPosterMoviePaths =  MovieDataParser.getMoviePosterPaths(mMovieJsonStr);
       }
       mMoviesAdapter = new MovieAdapter(Your_Activity_Name.this, mPosterMoviePaths);
       mMoviesGrid.setAdapter(mMoviesAdapter);
    }
    

    For Reference have a look at below link

    http://developer.android.com/reference/android/os/AsyncTask.html

    public class FetchMovieData extends AsyncTask <String, Void, Void> {
    
    @Override
    protected Void 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;
    
        try {
            // Construct the URL for the OpenWeatherMap query
            // Possible parameters are available at OWM's forecast API page, at
            // http://openweathermap.org/API#forecast
            URL url = new URL(getString(R.string.picasso_url_popular_movies));
    
            // Create the request to OpenWeatherMap, and open the connection
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();
    
            // Read the input stream into a String
            InputStream inputStream = urlConnection.getInputStream();
            StringBuffer buffer = new StringBuffer();
            if (inputStream == null) {
                // Nothing to do.
                mMovieJsonStr = 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 + "\n");
            }
    
            if (buffer.length() == 0) {
                // Stream was empty.  No point in parsing.
                mMovieJsonStr = null;
            }
            mMovieJsonStr = buffer.toString();
        } catch (IOException e) {
            Log.e("PlaceholderFragment", "Error ", e);
            // If the code didn't successfully get the weather data, there's no point in attempting
            // to parse it.
            mMovieJsonStr = null;
        } finally{
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (final IOException e) {
                    Log.e("PlaceholderFragment", "Error closing stream", e);
                }
            }
        }
    
        return null;
      }
     ****Below is the onPostExecute method****
    
    @Override
    protected void onPostExecute(String result) {
       if(mMovieJsonStr != null){
        mPosterMoviePaths =  MovieDataParser.getMoviePosterPaths(mMovieJsonStr);
       }
       mMoviesAdapter = new MovieAdapter(Your_Activity_Name.this, mPosterMoviePaths);
       mMoviesGrid.setAdapter(mMoviesAdapter);
    }
    
    }
    

    and extend your activity with Activity

    public class MainActivity extends Activity {
    }