2016-11-03 3 views
0

У меня есть список. В элементах строки у меня есть кнопка для стирания строки. Когда я нажимаю, я выполняю запрос volley на мой удаленный сервер, и если ответ был в порядке, я продолжаю удаление строки.Android Litsview не освежает после удаления строки

Проблема в том, что иногда я получаю положительный ответ от запроса волейбола, говоря, что моя строка была удалена на сервере. Но, чтобы не делать новое обновление с сервера, мой код для удаления строки из адаптера иногда не работает.

В других случаях адаптер удаляет строку и обновляется нормально.

Возникает ли проблема при вызове процедуры удаления строки в ответе запроса на залп?

Вот мой адаптер:

public class ListviewAgendaAdapter extends ArrayAdapter<ObjectAgenda> { 
    private int selected = -1; 
    ArrayList<ObjectAgenda> items; 
    private Activity context; 


    public ListviewAgendaAdapter(Activity context, ArrayList<ObjectAgenda> items) { 
     super(context, R.layout.singlerowagenda, items); 
     this.context = context; 
     this.items = items; 
    } 

    public void add(ObjectAgenda oa){ 
     this.items.add(oa); 
    } 

    public void setData(ArrayList<ObjectAgenda> items) { 
     this.items = items; 
     notifyDataSetChanged(); 
    } 

    public void select(int position) { 
     this.selected = position; 
     notifyDataSetChanged(); 
    } 

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

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

    public void deleteRowFromUi(int position) { 
     this.items.remove(position); 
     notifyDataSetChanged(); 
     notifyDataSetInvalidated(); 
    } 

    @Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 
     ObjectAgenda o = items.get(position); 
     final ViewHolder holder; 
     View vi = convertView; 
     if (vi == null){ 
      LayoutInflater inflater = context.getLayoutInflater(); 
      vi = inflater.inflate(R.layout.singlerowagenda, null);// e' preciso fazer o inflate pois a view nao ainda nao esta em activity alguma 
      holder = new ViewHolder(); 
      holder.tvIndice = (TextView) vi.findViewById(R.id.tvindice); 
      holder.tvNomeMed = (TextView) vi.findViewById(R.id.tvnomemed); 
      holder.butdesmarca = (Button) vi.findViewById(R.id.butdesmarcar); 
      holder.butdesmarca.setTag(position); 
      holder.butdesmarca.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        Integer index = (Integer) view.getTag(); 
        desmarca_agenda(index); 
       } 
      }); 

      vi.setTag(holder); 
     } 
     else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 
     if(selected != -1 && position == selected) { 
      vi.setBackgroundColor(context.getResources().getColor(R.color.red)); 
     }else vi.setBackgroundColor(context.getResources().getColor(R.color.white)); 

     holder.tvIndice.setText(String.valueOf(o.getIndice())); 
     holder.tvNomeMed.setText(o.getNome_med()); 
     return vi; 
    } 

    static class ViewHolder { 
     TextView tvIndice, tvNomeMed; 
     Button butdesmarca; 

    } 

private void desmarca_agenda(final Integer position) { 
       JSONArray ja = new JSONArray(); 
       ja.put(indice); 
       String mot=textMot.getText().toString().trim(); 
       if (TextUtils.isEmpty(mot)) mot="Não especificado"; 
       ja.put(mot); 
       JSONObject jsonBody = new JSONObject(); 
       try { 
        jsonBody.put("_parameters", ja); 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
       JsonObjectRequest jr = new JsonObjectRequest(Request.Method.POST, url, 
         jsonBody, new Response.Listener<JSONObject>() { 

        @Override 
        public void onResponse(JSONObject response) { 
         // TODO Auto-generated method stub 
         String s = ""; 
         try { 
          JSONArray LResult = response.getJSONArray("result"); 
          s = LResult.get(0).toString(); 
         } catch (JSONException e) { 
          e.printStackTrace(); 
         } 
         if (s.equals("true")) { 
          deleteRowFromUi(position.intValue()); 
         } 
        } 

       }, new Response.ErrorListener() { 

        @Override 
        public void onErrorResponse(VolleyError error) { 
         error.printStackTrace(); 
        } 
       }); 
       Common.getInstance().addToReqQueue(jr, "jreq"); 

      } 

Вот мой фрагмент с помощью адаптера:

public class AgendaMedFragment extends Fragment { 
    private static final String TAG = AgendaMedFragment.class.getSimpleName(); 
    ListviewAgendaAdapter adapter; 
    ArrayList<ObjectAgenda> items; 


    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.agendamedfrag, null); 

     final ListView listView = (ListView) view.findViewById(R.id.list_cons); 
     View v = (View) view.findViewById(R.id.empty_cons); 
     listView.setEmptyView(v); 
     items = new ArrayList<ObjectAgenda>(); 
     adapter = new ListviewAgendaAdapter(getActivity(), items); 
     listView.setAdapter(adapter); 

     Button but_data_execute= (Button) view.findViewById(R.id.but_data_agenda_execute); 
     but_data_execute.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       execute_get_agendamentos(); 
      } 
     }); 

     execute_get_agendamentos(); 
     return view; 
    } 



    private void parseJSONResponseAgendamentos(JSONObject response) { 
     try { 

      JSONArray LResult = response.getJSONArray("result"); 
      String s = LResult.get(0).toString(); 
      JSONArray entries = new JSONArray(s); 

      items.clear(); 
      for (int count = 0; count < entries.length(); count++) { 
       JSONObject anEntry = entries.getJSONObject(count); 

       String email = Common.getInstance().obag.getEmail(); 
       String senha = Common.getInstance().obag.getSenha(); 
       items.add(new ObjectAgenda(email, senha)); 
      } 
      adapter.setData(items); 
      adapter.notifyDataSetChanged(); 

     } catch (JSONException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 
    private void execute_get_agendamentos() { 
     String url = Common.getServerURL() + "\"ag_get_ag\""; 

     JSONArray ja = new JSONArray(); 
     String email = "email" 
     String senha = "pass" 
     ja.put(email); 
     ja.put(senha); 
     JSONObject jsonBody = new JSONObject(); 
     try { 
      jsonBody.put("_parameters", ja); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
     JsonObjectRequest jr = new JsonObjectRequest(Request.Method.POST, url, 
       jsonBody, new Response.Listener<JSONObject>() { 

      @Override 
      public void onResponse(JSONObject response) { 
       parseJSONResponseAgendamentos(response); 

      } 

     }, new Response.ErrorListener() { 

      @Override 
      public void onErrorResponse(VolleyError error) { 
       error.printStackTrace(); 
      } 
     }); 

     Common.getInstance().addToReqQueue(jr, "jreq"); 
    } 

} 

ответ

0

Я думаю, что удаление notifyDataSetInvalidated(); решила бы эту проблему

+0

Я уже использую его в «deleteRowFromUi». Он не решает проблему. –

+0

Мой первоначальный код: items.remove (position.intValue()); notifyDataSetChanged(); но у меня была та же проблема. Затем добавляю notifyDataSetInvalidated(); и проблема продолжается. –

+0

Вам нужно только оповещать файл DataSetChanged, и вы не используете его правильно. Вы пытаетесь вызвать локальную переменную, используя эту команду, если хотите, чтобы глобальная переменная «элементы» вы должны удалить «это» – Gabe

0

Ваш ArrayAdapter и ваш класс-ссылка на items не синхронизированы, вероятно, потому, что вы вызвали ваш метод setData(List<ObjectAgenda>).

Если вам действительно нужна ссылка класса на ваши данные, вам нужно изменить пару вещей.

public void setData(ArrayList<ObjectAgenda> items) { 
    super.clear(); 

    for(ObjectAgenda a : items) 
     super.add(a); 

    this.items = items; 

    notifyDataSetChanged(); 
} 

А также:

public void deleteRowFromUi(int position) { 
    super.remove(getItem(position)); 

    this.items.remove(position); 

    notifyDataSetChanged(); 
} 

Лично, хотя, я бы избавиться от своего класса ссылок на пункты полностью и использовать только встроенные методы в ArrayAdapter, поскольку там действительно нет оснований для Вас для этого ... Это просто дополнительная работа, поддерживающая ссылки в синхронизации.

+0

К сожалению, с этими изменениями мой список не заполнен. У меня есть пустой список. –

+0

У меня есть запрос на звонок на мой сервер. При ответе в порядке, я делаю следующий, чтобы заполнить listview: items.clear(); for (int count = 0; count

+0

Вы должны оформить в [код ArrayAdapter] (https://github.com/android/platform_frameworks_base/ blob/master/core/java/android/widget/ArrayAdapter.java) и посмотрите на переменную 'List mObjects'. Вы должны заметить, что в сочетании с реализацией вашего адаптера вы фактически работаете с 2 списками, синхронизировать друг с другом, а не единственный список, который поддерживает адаптер, как вы думаете. – Guardanis

Смежные вопросы