Ich versuche herauszufinden, wo das Problem beim Aktualisieren RecyclerView
des Adapters liegt.
Nachdem ich eine neue Produktliste erhalten hatte, versuchte ich:
Aktualisieren Sie das
ArrayList
aus dem Fragment, in demrecyclerView
es erstellt wurde, setzen Sie neue Daten auf den Adapter und rufen Sie dann aufadapter.notifyDataSetChanged()
. Es hat nicht funktioniert.Erstellen Sie einen neuen Adapter, wie andere es getan haben, und es hat für sie funktioniert, aber für mich keine Änderung:
recyclerView.setAdapter(new RecyclerViewAdapter(newArrayList))
Erstellen Sie eine Methode, mit
Adapter
der die Daten wie folgt aktualisiert werden:public void updateData(ArrayList<ViewModel> viewModels) { items.clear(); items.addAll(viewModels); notifyDataSetChanged(); }
Dann rufe ich diese Methode auf, wenn ich die Datenliste aktualisieren möchte. Es hat nicht funktioniert.
So überprüfen Sie, ob ich die recyclerView auf irgendeine Weise ändern kann, und ich habe versucht, mindestens ein Element zu entfernen:
public void removeItem(int position) { items.remove(position); notifyItemRemoved(position); }
Alles blieb wie es war.
Hier ist mein Adapter:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> implements View.OnClickListener {
private ArrayList<ViewModel> items;
private OnItemClickListener onItemClickListener;
public RecyclerViewAdapter(ArrayList<ViewModel> items) {
this.items = items;
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler, parent, false);
v.setOnClickListener(this);
return new ViewHolder(v);
}
public void updateData(ArrayList<ViewModel> viewModels) {
items.clear();
items.addAll(viewModels);
notifyDataSetChanged();
}
public void addItem(int position, ViewModel viewModel) {
items.add(position, viewModel);
notifyItemInserted(position);
}
public void removeItem(int position) {
items.remove(position);
notifyItemRemoved(position);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
ViewModel item = items.get(position);
holder.title.setText(item.getTitle());
Picasso.with(holder.image.getContext()).load(item.getImage()).into(holder.image);
holder.price.setText(item.getPrice());
holder.credit.setText(item.getCredit());
holder.description.setText(item.getDescription());
holder.itemView.setTag(item);
}
@Override
public int getItemCount() {
return items.size();
}
@Override
public void onClick(final View v) {
// Give some time to the ripple to finish the effect
if (onItemClickListener != null) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
onItemClickListener.onItemClick(v, (ViewModel) v.getTag());
}
}, 0);
}
}
protected static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView image;
public TextView price, credit, title, description;
public ViewHolder(View itemView) {
super(itemView);
image = (ImageView) itemView.findViewById(R.id.image);
price = (TextView) itemView.findViewById(R.id.price);
credit = (TextView) itemView.findViewById(R.id.credit);
title = (TextView) itemView.findViewById(R.id.title);
description = (TextView) itemView.findViewById(R.id.description);
}
}
public interface OnItemClickListener {
void onItemClick(View view, ViewModel viewModel);
}
}
Und ich initiiere RecyclerView
wie folgt:
recyclerView = (RecyclerView) view.findViewById(R.id.recycler);
recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 5));
adapter = new RecyclerViewAdapter(items);
adapter.setOnItemClickListener(this);
recyclerView.setAdapter(adapter);
Wie aktualisiere ich die Adapterdaten, um neu empfangene Elemente anzuzeigen?
Update: Das Problem war, dass das Layout, in dem gridView angezeigt wurde, wie folgt aussah:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:tag="catalog_fragment"
android:layout_height="match_parent">
<FrameLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"/>
<ImageButton
android:id="@+id/fab"
android:layout_gravity="top|end"
style="@style/FabStyle"/>
</FrameLayout>
</LinearLayout>
Dann habe ich einfach entfernt LinearLayout
und FrameLayout
als übergeordnetes Layout erstellt.
items.clear(); items.addAll(newItems);
ist ein hässliches Muster. Wenn Sie hier wirklich defensives Kopieren brauchen,items = new ArrayList(newItems);
wäre das weniger hässlich.