5

I've been looking around everywhere in trying to find out why my code was causing an issue. I have a GridView that has an ArrayAdapter which pulls photos down with an AsyncTask. I can see the items being updated but when I try to update the adapter the GridView doesn't seem to update with the new view.

This is the relevant code that does the work...

private void fetchJsonResponse(String url) {
    // Pass second argument as "null" for GET requests
    JsonObjectRequest req = new JsonObjectRequest(Request.Method.GET,
            url + "&api_key=" + API_KEY,
            null,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    try {
                        JSONArray photos = response.getJSONArray("photos");

                        for(int i = 0; i < photos.length(); i++){
                            JSONObject object = photos.getJSONObject(i);
                            String url = object.getString("img_src");
                            //String id = object.getString("id");
                            list.add(new ImageItem(null, "Picture", url));
                            Log.i("Debug 2", url);
                        }
                        Log.i("Debug 2", list.get(0).toString());

                        if(gridViewAdapter != null){
                            gridViewAdapter.clear();
                            gridViewAdapter.addAll(list);
                            gridViewAdapter.notifyDataSetChanged();
                            gridView.invalidateViews();
                        } else {
                            gridViewAdapter = new GridViewAdapter(getActivity(), R.layout.gridview_item, list);
                            gridView.setAdapter(gridViewAdapter);
                        }




                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            VolleyLog.e("Error: ", error.getMessage());
        }
    });



    /* Add your Requests to the RequestQueue to execute */
    mRequestQueue.add(req);

}

private class MyAsyncTask extends AsyncTask<String, Void, Void> {
    private ProgressDialog progressDialog;
    private Context context;

    public MyAsyncTask (Context context){
        this.context = context;
        progressDialog = new ProgressDialog(getActivity());
        progressDialog.setMessage("Contacting Rover...");
    }

    @Override
    protected Void doInBackground(String... strings) {
        fetchJsonResponse(strings[0]);
        return null;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        Toast.makeText(getActivity(), "In Pre Execute", Toast.LENGTH_SHORT).show();
        progressDialog.show();

    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        progressDialog.dismiss();
    }
}

I would really appreciate any help if possible. Trying to get the app out before new years :).

Maybe If you could tell me why this happens so It won't cause an issue again and other will see.

EDIT: Added a bit more code which has it refreshing after I click the button twice.

private void fetchJsonResponse(String url) {
    // Pass second argument as "null" for GET requests
    JsonObjectRequest req = new JsonObjectRequest(Request.Method.GET,
            url + "&api_key=" + API_KEY,
            null,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    try {
                        JSONArray photos = response.getJSONArray("photos");
                        list.clear();
                        for(int i = 0; i < photos.length(); i++){
                            JSONObject object = photos.getJSONObject(i);
                            String url = object.getString("img_src");
                            list.add(new ImageItem(null, "Picture", url));
                            Log.i("Debug 2", url);
                        }
                        Log.i("Debug 2", list.get(0).toString());

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            VolleyLog.e("Error: ", error.getMessage());
        }
    });



    /* Add your Requests to the RequestQueue to execute */
    mRequestQueue.add(req);

}

private class MyAsyncTask extends AsyncTask<String, Void, Void> {
    private ProgressDialog progressDialog;
    private Context context;

    public MyAsyncTask (Context context){
        this.context = context;

        progressDialog = new ProgressDialog(getActivity());
        progressDialog.setMessage("Contacting Rover...");
        pictureAdapter = new PictureAdapter(getActivity(), list);
        gridView.setAdapter(pictureAdapter);
    }

    @Override
    protected Void doInBackground(String... strings) {
        fetchJsonResponse(strings[0]);
        return null;
    }

    @Override
    protected void onPreExecute() {
        progressDialog.show();
        super.onPreExecute();
        Toast.makeText(getActivity(), "In Pre Execute", Toast.LENGTH_SHORT).show();


    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);

        pictureAdapter.updateItemList(list);
        gridView.invalidate();

        progressDialog.dismiss();
    }
}

Adapter:

public class PictureAdapter extends BaseAdapter {
private ArrayList<ImageItem> items;
private Context context;
private TextView titleText;
private ImageView itemImage;

public PictureAdapter(Context context, ArrayList<ImageItem> items){
    this.context = context;
    this.items = items;
}

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

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

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = LayoutInflater.from(context).inflate(R.layout.gridview_item, parent, false);

    titleText = (TextView) v.findViewById(R.id.text);
    itemImage = (ImageView)v.findViewById(R.id.image);

    titleText.setText(items.get(position).getTitle());
    Picasso.with(context).load(items.get(position).getUrl()).fit().into(itemImage);

    return v;
}

public void updateItemList(ArrayList<ImageItem> newItemList){
    this.items = newItemList;
    notifyDataSetChanged();
}

}
SmiffyKmc
  • 801
  • 1
  • 16
  • 34
  • http://stackoverflow.com/questions/24874177/gridview-is-not-refreshing-view-after-data-changed?rq=1 might be useful – Manohar Dec 24 '16 at 11:27
  • Are you getting any errors? Although im not sure, but it seems like youre trying to do the calls to the adapter and the view on a non-ui thread. What thread does the responseListener execute? – Mehmet K Dec 24 '16 at 11:28
  • @Redman Thanks! I'll have a look at that and see if I can use ViewHolder. Anything helps! No errors, I even see the picture urls coming in so shows they are there. I assume it's executing on a background thread. It's being called in the AsyncTask which is working on the background too though no? Thanks very much for the help! – SmiffyKmc Dec 24 '16 at 11:33
  • 1
    update your gridview inside runOnUiThread() method if you are doing in activity or use Handler which will run on ui thread – sohan shetty Dec 24 '16 at 11:36
  • I took the if/else section which should update GridView and put into onPostExecute as that runs on the UI Thread but it doesn't seem to update at all now... – SmiffyKmc Dec 24 '16 at 11:52
  • Please take a look at this [question](http://stackoverflow.com/questions/19807147/get-json-data-in-listview-with-asynctask) - you can pass your list as return value from `doInBackground`, update your UI in `onPostExecute` with your fetched data. Do something like `list.clear(); list.addAll(listFromDoInBackground); adapter.notifyDataSetChanged();` or instantiate a new `adapter` if it is null. I would also recommend using the `ViewHolder` pattern or a `RecyclerView`. – yennsarah Jan 10 '17 at 14:18
  • If you are using volley then there no need of asynctask remove that – Narendra Kothamire Jan 11 '17 at 04:48
  • have you tried with putting break-point and flow.? – Noorul Jan 11 '17 at 05:32
  • @SmiffyKmc does it work properly the first time you click the button? Meaning the first time you start up the app, or do you always have to double-click? – Pztar Jan 13 '17 at 02:12

2 Answers2

1

Try the below lines in post execute

@Override
protected void onPostExecute(Void aVoid) {
    super.onPostExecute(aVoid);

    pictureAdapter.updateItemList(list,gridView);
    progressDialog.dismiss();
}

Now in your updateItemList

public void updateItemList(ArrayList<ImageItem> newItemList,GridView gridView){
    this.items = newItemList;

    gridView.setAdapter(null);
    gridView.invalidateViews();
    gridView.deferNotifyDataSetChanged();

    gridView.setAdapter(list);

}
Ranjan
  • 1,326
  • 18
  • 38
1

Why you are calling Volley request from AsyncTask as Volley perform request on NetworkThread.

Remove AsyncTask and directly call Volley.

Just try this. Hope it helps.

private ProgressDialog progressDialog;

protected void onCreate(Bundle savedInstanceState) {
    progressDialog = new ProgressDialog(getActivity());
    progressDialog.setMessage("Contacting Rover...");
    progressDialog.show();
    fetchJsonResponse(url); 
}

private void fetchJsonResponse(String url) {
    // Pass second argument as "null" for GET requests
    JsonObjectRequest req = new JsonObjectRequest(Request.Method.GET,
            url + "&api_key=" + API_KEY,
            null,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    progressDialog.dismiss();
                    try {
                        JSONArray photos = response.getJSONArray("photos");
                        list.clear();
                        for(int i = 0; i < photos.length(); i++){
                            JSONObject object = photos.getJSONObject(i);
                            String url = object.getString("img_src");
                            list.add(new ImageItem(null, "Picture", url));
                            Log.i("Debug 2", url);
                        }
                        pictureAdapter.notifyDataSetChanged();
                        Log.i("Debug 2", list.get(0).toString());

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }, 
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    progressDialog.dismiss();
                    VolleyLog.e("Error: ", error.getMessage());
                }
            });
    /* Add your Requests to the RequestQueue to execute */
    mRequestQueue.add(req);
}
Jaymin Panchal
  • 2,797
  • 2
  • 27
  • 31