2016-12-24 55 views
5

Szukałem wszędzie, próbując dowiedzieć się, dlaczego mój kod powodował problem. Mam GridView, który ma ArrayAdapter, który ściąga zdjęcia za pomocą AsyncTask. Widzę, że elementy są aktualizowane, ale kiedy próbuję zaktualizować adapter, GridView wydaje się nie aktualizować z nowym widokiem.GridView nie aktualizuje swoich widoków podrzędnych po tym, jak adapter otrzymuje nowe elementy.

Jest odpowiedni kod, który działa ...

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(); 
    } 
} 

Ja naprawdę wdzięczni za każdą pomoc, jeśli to możliwe. Próbuję dostać aplikację przed nowymi latami :).

Może Jeśli możesz mi powiedzieć, dlaczego tak się dzieje, To nie spowoduje problemu ponownie, a inni zobaczą.

EDYCJA: Dodano nieco więcej kodu, który ma odświeżenie po dwukrotnym kliknięciu przycisku.

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(); 
} 

} 
+0

http://stackoverflow.com/questions/24874177/gridview-is-not-refreshing-view-after-data-changed?rq=1 może być przydatna – Redman

+0

Czy otrzymujesz jakieś błędy? Chociaż nie jestem pewien, ale wydaje się, że próbujesz wykonać wywołania do adaptera i widoku na wątku non-ui. W jakim wątku wykonywany jest element responseListener? –

+0

@Redman Dzięki! Przyjrzę się temu i zobaczę, czy mogę użyć ViewHolder. Wszystko pomaga! Bez błędów, widzę nawet adresy URL obrazów, więc pokazują, że są. Zakładam, że działa na wątku tła. To jest wywoływane w AsyncTask, który działa również w tle, ale nie? Bardzo dziękuję za pomoc! – SmiffyKmc

Odpowiedz

1

Wypróbuj poniższe linie w poście wykonać

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

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

teraz w Twoich updateItemList

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

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

    gridView.setAdapter(list); 

} 
1

Dlaczego dzwonisz Volley wniosek AsyncTask jako Volley wykonaj żądanie na NetworkThread.

Usuń AsyncTask i bezpośrednio zadzwoń pod numer Volley.

Po prostu spróbuj tego. Mam nadzieję, że to pomoże.

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