Search code examples
androidgridviewandroid-fragmentactivity

Unable to get GridView in FragmentActivity


When I implement the GridView in the Fragment instead of the MainActivity class and after I run the app on my phone, the screen is blank. The app fetches the data from the server correctly but does not show anything on the mobile screen.

Here is my MainActivityFragment class :

public class MainActivityFragment extends Fragment {

private GridView gridView;
private GridViewAdapter gridAdapter;
private ArrayList<ImageItem> data;
public MainActivityFragment() {
}

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

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

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragment_main, container, false);

    data = new ArrayList<>();
    gridView = (GridView) rootView.findViewById(R.id.gridView);
    gridAdapter = new GridViewAdapter(getActivity(), R.layout.grid_poster, data);
    gridView.setAdapter(gridAdapter);
    return super.onCreateView(inflater, container, savedInstanceState);
}

@Override
public void onStart() {
    super.onStart();
    FetchPosterTask posterTask = new FetchPosterTask();
    posterTask.execute();
}

public class FetchPosterTask extends AsyncTask<Void, Void, Integer> {

    private final String LOG_TAG = FetchPosterTask.class.getSimpleName();

    private Integer parseResult(String result)
            throws JSONException{

            JSONObject response = new JSONObject(result);
            JSONArray movies = response.getJSONArray("results");
            ImageItem item = new ImageItem();
            for (int i = 0; i < movies.length(); i++) {
                JSONObject movie = movies.optJSONObject(i);

                item = new ImageItem();
                String posterPath = movie.getString("poster_path");
                Uri.Builder builder = new Uri.Builder();
                builder.scheme("https")
                        .authority("image.tmdb.org")
                        .appendPath("t")
                        .appendPath("p")
                        .appendPath("w185");
                String poster  = builder.toString()+posterPath;
                item.setImage(poster);
                Log.v(LOG_TAG, "poster_path " + poster);
                }
                data.add(item);
             return 1;
    }

    @Override
    protected Integer doInBackground(Void... params) {

        Integer result = 0;
        HttpURLConnection urlConnection = null;
        String moviesJasonStr = null;
        String sort_by = "popularity.desc";
        BufferedReader reader = null;
        try {
            final String baseUrl = "http://api.themoviedb.org/3/discover/movie?";
            final String QUERY_PARAM = "sort_by";
            final String APPID_PARAM = "api_key";
            Uri builtUri = Uri.parse(baseUrl).buildUpon()
                    .appendQueryParameter(QUERY_PARAM, sort_by)
                    .appendQueryParameter(APPID_PARAM, BuildConfig.OPEN_MOVIES_API_KEY)
                    .build();
            URL url = new URL(builtUri.toString());
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();

            InputStream inputStream = urlConnection.getInputStream();
            StringBuffer buffer = new StringBuffer();
            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 + "\n");
            }

            if (buffer.length() == 0) {
                // Stream was empty.  No point in parsing.
                return null;
            }
            moviesJasonStr = buffer.toString();

            Log.v(LOG_TAG, "moviesJasonStr: " + moviesJasonStr);


        } catch (IOException e) {
            Log.e(LOG_TAG, "Error ", e);
            // If the code didn't successfully get the weather data, there's no point in attemping
            // to parse it.
            return null;
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (final IOException e) {
                    Log.e(LOG_TAG, "Error closing stream", e);
                }

            }
        }
        try {
            return parseResult(moviesJasonStr);
        } catch (JSONException e) {
            Log.e(LOG_TAG, e.getMessage(), e);
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Integer integer) {
        Log.v(LOG_TAG, "result_integer: " + integer);
        if (integer == 1) {
            gridAdapter.setGridData(data);
        } else {
            Toast.makeText(getActivity(), "Failed to fetch data!", Toast.LENGTH_SHORT).show();
        }
    }
}

}

This is my GridViewAdapter class :

public class GridViewAdapter extends ArrayAdapter<ImageItem> {

private Context context;
private int layoutResourceId;
private ArrayList<ImageItem> data = new ArrayList<ImageItem>();

public GridViewAdapter(Context context, int layoutResourceId, ArrayList<ImageItem> data) {
    super(context, layoutResourceId, data);
    this.layoutResourceId = layoutResourceId;
    this.context = context;
    this.data = data;
}
/**
 * Updates grid data and refresh grid items.
 * @param data
 */
public void setGridData(ArrayList<ImageItem> data) {
this.data = data;
    notifyDataSetChanged();
}



@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    ViewHolder holder;

    if (row == null) {
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        row = inflater.inflate(layoutResourceId, parent, false);
        holder = new ViewHolder();
        holder.image = (ImageView) row.findViewById(R.id.image);
        row.setTag(holder);
    } else {
        holder = (ViewHolder) row.getTag();
    }


    ImageItem item = data.get(position);
    //holder.image.setImageBitmap(item.getImage());
    Picasso.with(context).load(item.getImage()).into(holder.image);
    return row;
}

static class ViewHolder {
    ImageView image;
}

}

and this is my fragment_main.xml file:

<RelativeLayout 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:background="#f0f0f0"
tools:context = ".MainActivityFragment">

<GridView
    android:id="@+id/gridView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:columnWidth="100dp"
    android:drawSelectorOnTop="true"
    android:gravity="center"
    android:numColumns="auto_fit"
    android:stretchMode="columnWidth"
    android:verticalSpacing="5dp"
    android:focusable="true"
    android:clickable="true"/>
   </RelativeLayout>

Solution

  • First of all return rootView in onCreate

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
    
        data = new ArrayList<>();
        gridView = (GridView) rootView.findViewById(R.id.gridView);
        gridAdapter = new GridViewAdapter(getActivity(), R.layout.grid_poster, data);
        gridView.setAdapter(gridAdapter);
        return rootView;
    }
    

    and if its not working then set adapter in onPostexecute