2017-03-24 14 views
-2

Wie kann ich interne Daten in einem RecyclerView aktualisieren, der an eine öffentliche statische Variable gebunden ist? Ich habe diese Adapterklasse erstellt und alle (ich denke) definiert, die ich brauche, um eine Liste von Objekten zu erstellen, die über eine RecyclerView angezeigt werden. Nun, wie Sie im Konstruktor sehen können, gibt es eine interne ArrayList, die durch Abrufen der Daten von einer öffentlichen statischen ArrayList an anderer Stelle erstellt wird.RecyclerView: Aktualisieren von Daten

public class MyListAdapter extends RecyclerView.Adapter<MyListAdapter.ViewHolder> { 

private ArrayList<StatusBarNotification> myList; 
Context ctx; 

public class ViewHolder extends RecyclerView.ViewHolder { 
    public ImageView appSmallIcon; 

    public ViewHolder(View v) { 
     super(v); 
     appSmallIcon = // .. 
    // .... 
    } 
} 

public void add(int position, StatusBarNotification item) { 
    myList.add(position, item); 
    notifyItemInserted(position); 
} 

public void remove(StatusBarNotification item) { 
    int position = myList.indexOf(item); 
    myList.remove(position); 
    notifyItemRemoved(position); 
} 

public MyListAdapter(Context context) { 
    if (MyService.allMyData != null) 
     myList = new ArrayList<>(MyService.allMyData); 
    else 
     myList = new ArrayList<>(); 
    ctx = context; 
} 

@Override 
public MyListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View v = //... 
    ViewHolder vh = new ViewHolder(v); 
    return vh; 
} 

@Override 
public void onBindViewHolder(ViewHolder holder, int position) { 
    // .... 
} 

@Override 
public int getItemCount() { 
    return myList.size(); 
} 

}

Nach dem RecyclerView erstellt wird, und die App läuft, was soll ich tun mitteilen, dass die externe myAllData Arraylist geändert hat, oder ein Element hinzugefügt oder entfernt? Ich habe versucht, notifyDataSetChanged() aufzurufen, aber nichts passiert. Das Seltsame (in meinen Augen natürlich) ist, dass ich keinen Zugriff auf Methoden wie add(), remove() habe.

Angenommen, notifyDataSetChanged() ist die richtige Straße zu folgen, wo sollte ich einen Listener in den Adapter setzen, um die internen Daten tatsächlich zu aktualisieren und den RecyclerView auffordern, den Bildschirm zu aktualisieren? Soll ich stattdessen Intents verwenden, um mit meinem Adapter zu kommunizieren?

Und auch, warum Java mich verhindert, so etwas zu tun:

MyListAdapter myLA = new MyListAdapter(....); 
myLA.remove(item); // <-- why the public method remove() is not available?!? 

Ich verstehe nicht, die Syntax und Semantik, die mich von dem Zugriff auf die öffentlichen Methoden verhindern, als ob sie privat waren. Versuchen

+1

Kann jemand den Grund für die Downvotes erklären? –

Antwort

0

Es scheint, dass mein Problem war, dass ich vermutete, dass ich eine interne private Variable behalten musste, die mit den realen externen Daten synchronisiert wurde, um gezeigt zu werden. Ich habe mich geirrt: Der Adapter muss direkt mit den Daten verbunden sein, die angezeigt werden müssen, durch eine Referenz. Die private Kopie ist nur eine private Referenz auf die öffentlichen Daten, also Kopieren der adressierten Daten im Konstruktor ist falsch. Wenn der Konstruktor des Adapters zu diesem Zeitpunkt den Verweis auf ein Datenobjekt erhält, kann er bei jeder Änderung mit notifyDataSetChanged() gemeldet werden.

+0

Hi kannst du das weiter ausbauen? Ich denke, ich habe ein ähnliches Problem –

0

Diese

public MyListAdapter(Context context) { 
if (MyService.allMyData != null) 
{ 
    // myList = new ArrayList<>(MyService.allMyData); // This type of initialization don't allow mofification in list. or you can do this 

     myList = new ArrayList<>(Arrays.asList(MyService.allMyData)); 
     // or 
     myList = new ArrayList<>(); 
     myList.addAll(MyService.allMyData); 
} 
    else 
    myList = new ArrayList<>(); 
    ctx = context; 
} 
+0

Leider ist das Problem nicht im Konstruktor. Beim Aufruf von notifyDataSetChanged() wird der Konstruktor nicht erneut ausgeführt. Danke trotzdem, dass Sie versuchen, mir mit einer Lösung zu helfen, nach 2 Tagen Kopf gegen Docs und Tutorials, anstelle von denen, die eine Programmierfrage ablehnen. –

+0

Ihre Begrüßung. Ja Konstruktor wird nur einmal aufgerufen. –

0

Sie notifyDataSetChanged verwenden können, wenn Sie Rendering-Probleme auftreten versuchen requestLayout und forceLayout.

+0

Eigentlich notifyDataSetChanged tut nichts. Es benachrichtigt registrierte Beobachter für Datenänderungen, aber wie kann ich die Daten ändern? Das ist das Problem. –

Verwandte Themen