2013-02-22 1 views
12

Ich habe eine Liste, die vom Benutzer aktualisiert werden kann, aber notifyDataSetChanged() funktioniert nicht auf dem Adapter, der mit der listView verbunden ist. Ich benutze es in einem Fragment. Database wird aktualisiert, der Adpater jedoch nicht. Folgende ist meine Umsetzung:ArrayAdapter.NotifyDataSetChanged() funktioniert nicht?

Mein Haupt 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; 
} 

Nach einigen Navigationsprozessliste aktualisiert wird und in meinem onResume() Methode, die ich die aktualisierte Liste aus der Datenbank erhalten und notifyDatasetChanged() Methode aufrufen, die nicht aktualisiert meine Ansicht, jedoch wird das entsprechende Array aus der DB aktualisiert.

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

Jeder Gedanke auf, was nicht in Ordnung ist? Warum wird listview nicht aktualisiert? Irgendwelche Hilfe wird geschätzt.

+0

Ist das 'adapter.setItems' einige benutzerdefinierte Methode, die Sie gemacht? – Sean

+0

@Sean ja..Es ist eine benutzerdefinierte Methode. –

+0

post myListAdapter – Blackbelt

Antwort

26

notifyDataSetChanged() wird nicht für Sie arbeiten. Gründe warum

  1. Ihr Adapter verliert den Verweis auf Ihre Liste.
  2. Erstellen und Hinzufügen einer neuen Liste zum Adapter. Gehen Sie wie folgt vor: initialisieren Sie die ArrayList, während Sie global deklarieren.

    ArrayList<myList> myArrayList=new ArrayList<myList>(); // als globaler Variable

    Liste hinzufügen Auf den Adapter direkt mit aus null und leeren Zustand zu überprüfen. Setzen Sie den Adapter in die Liste direkt (nicht für jede Bedingung überprüfen)

    myListView.setAdapter(adapter);

  3. hinzufügen Daten an die myArrayList Jedes Mal (wenn Ihre Daten vollständig neu ist, als Sie rufen adapter.clear können() und myArrayList.clear() vor dem tatsächlichen Hinzufügen von Daten zur Liste), aber setzen Sie den Adapter nicht auf i.e Wenn die neuen Daten in dem myArrayList als adapter.notifyDataSetChanged()

    gerade bevölkert
    adapter = new myListAdapter(getActivity(), 0, myArrayList); 
    
  4. diese Zeile

    entfernen

    adapter.setItems (myArrayList);

+0

Vielen Dank ... Es funktionierte für mich ... –

+0

Danke für den Vorschlag, es funktioniert für mich !!! –

+0

nicht eine gute Sache, immer die neue Liste zu geben @ hovo888s Lösung arbeitete –

-2

Wenn Sie notifyDataSetChanged() aber in Adapter verwenden können! ein wenig Methode in

+0

Ich habe bereits von den Signaturen 'setItems (myArrayList)' –

0

erstellen Das Problem ist im Konstruktor von MyListAdapter

Statt

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

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

auch versuchen, anstelle von Ihnen Methode setItems besitzen sollten Sie adapter.clear(); nennen gefolgt von adapter.addAll(myArrayList);

4

Gerade overrige getCount Methode

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

In Ihrem setItems Methode versuchen, die alte ArrayList zu löschen.

statt dessen:

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

Versuchen Sie folgendes:

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

Dank Arbeit für mich. –

Verwandte Themen