2013-02-22 4 views
12

Mam listę, która może być aktualizowana przez użytkownika, ale notifyDataSetChanged() nie działa na karcie skojarzonej z listView. Używam go w fragmencie. Baza danych zostaje zaktualizowana, jednak nie ma jej adpater. Oto moja realizacja:ArrayAdapter.NotifyDataSetChanged() nie działa?

mój główny Fargment:

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    myArrayList = new ArrayList<myList>(); 
    myArrayList = Database.getSharedObject(getActivity()).getMyList(); 
    if (myArrayList != null && myArrayList.size() > 0) { 
     adapter = new myListAdapter(getActivity(), 0, myArrayList); 
    } 

} 

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

    View v = inflater.inflate(R.layout.mainfragment, container, false); 
    myListView = (ListView) v.findViewById(R.id.my_list_view); 
    myListView.setOnItemClickListener(this); 
    if (adapter != null) { 
     myListView.setAdapter(adapter); 
    } 

    return v; 
} 

Po kilku nawigacje Lista proces jest aktualizowany i moim sposobie onResume() uzyskać zaktualizowaną listę z bazy danych i wywołać notifyDatasetChanged() metodę, która nie aktualizuje mój view, jednak odpowiednia tablica z DB jest aktualizowana.

@Override 
public void onResume() { 
    super.onResume(); 
    myArrayList = Database.getSharedObject(getActivity()).getMyList(); 
    adapter.setItems (myArrayList); 
    adapter.notifyDataSetChanged(); 

} 

MyListAdapter

public class MyListAdapter extends ArrayAdapter<Message> { 

    private ArrayList<Message> myList; 

    /* Context */ 
    private Context context; 

    public void setItems (ArrayList<Message> myList) { 
     this.myList = myList; 
    } 

    public MyListAdapter (Context context, int textViewResourceId, ArrayList<Message> myList) { 
     super(context, textViewResourceId, myList); 
     this.context = context; 
     this.myList = myList; 
    } 

    @Override 
    public View getView (int position, View v, ViewGroup parent) { 
     // Keeps reference to avoid future findViewById() 
     MyViewHolder viewHolder; 

     if (v == null) { 
      LayoutInflater li = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v = li.inflate(R.layout.list_row, parent, false); 

      viewHolder = new MyViewHolder(); 
      viewHolder.txtImage = (ImageView) v.findViewById(R.id.message_icon); 
      viewHolder.txtMessage = (TextView) v.findViewById(R.id.message); 
      viewHolder.txtDate = (TextView) v.findViewById(R.id.date); 

      v.setTag(viewHolder); 
     } else { 
      viewHolder = (MyViewHolder) v.getTag(); 
     } 

     Message myMessage = new Message(); 
     myMessage = myList.get(position); 
     if (myMessage != null) { 
      viewHolder.txtMessage.setText(myMessage.getText()); 
      viewHolder.txtDate.setText(myMessage.getDate()); 
     } 
     return v; 
    } 

    static class MyViewHolder { 
     ImageView txtImage; 
     TextView txtMessage; 
     TextView txtDate; 
    } 
} 

Każda myśl o tym, co jest nie tak? Dlaczego lista nie jest aktualizowana? Każda pomoc jest doceniana.

+0

Czy 'adapter.setItems' jakiś sposób niestandardowy dokonane? – Sean

+0

@Sean yes..Jest to metoda niestandardowa. –

+0

post myListAdapter – Blackbelt

Odpowiedz

26

notifyDataSetChanged() nie będzie działać dla Ciebie. Powody, dla których

  1. Twoja karta traci odwołanie do listy.
  2. Zawsze tworzenie i dodawanie nowej listy do adaptera. Wykonaj następujące czynności: zainicjuj ArrayList podczas deklarowania globalnie.

    ArrayList<myList> myArrayList=new ArrayList<myList>(); // jako zmienną globalną

    Dodaj listę do adaptera bezpośrednio na sprawdzenie stanu zerowego i pusty. Ustaw adapter do listy bezpośrednio (nie sprawdzić, czy nie stanie)

    myListView.setAdapter(adapter);

  3. Dodaj dane do myArrayList każdym razem (jeśli dane są całkowicie nowe, niż można nazwać adapter.clear() i myArrayList.clear() przed dodaniem danych do listy), ale nie ustawiaj adaptera.e Jeśli nowe dane są wypełniane w myArrayList niż tylko adapter.notifyDataSetChanged()

    adapter = new myListAdapter(getActivity(), 0, myArrayList); 
    
  4. Usuń ten wiersz

    adapter.setItems (myArrayList);

+0

Dziękuję ... Udało mi się ... –

+0

Dzięki za sugestię, to działa dla mnie !!! –

+0

niezbyt dobrze jest zawsze podawać nową listę zamiast rozwiązania @ hovo888s pracował –

-2

Jeśli możesz użyć notifyDataSetChanged(), ale w adapterze! stworzyć małą metodę wewnątrz

+0

Stworzyłem już przez podpisy 'setItems (myArrayList)' –

0

Problem jest w konstruktorze MyListAdapter

Zamiast

public MyListAdapter(Context context, int textViewResourceId, ArrayList<Message> myList) { 
    super(context, textViewResourceId, scheduledMessageList); 
    this.context = context; 
    this.myList = myList; 
} 

spróbować

public MyListAdapter(Context context, int textViewResourceId, ArrayList<Message> myList) { 
    super(context, textViewResourceId, myList); 
    this.context = context; 
    this.myList = myList; 
} 

również zamiast Państwo własną metodę setItems należy zadzwonić adapter.clear(); następnie adapter.addAll(myArrayList);

4

Wystarczy overrige metody getCount

@Override 
    public int getCount() { 
     return myArrayList.count(); 
    } 
3

W swoim setItems metoda próbuje wyczyścić starą tablicę ArrayList.

zamiast tego:

public void setItems(ArrayList<Message> myList) { 
this.myList = myList; 
} 

Spróbuj tego:

public void setItems(ArrayList<Message> myList) { 
this.myList.clear(); 
this.myList.addAll(myList); 
notifyDataSetChanged(); 
} 
+0

dziękuję za pracę dla mnie. –