Nik*_*hil 14 android observers notifydatasetchanged recycler-adapter android-recyclerview
我RecyclerView用它实现了Custom Adapter如下
全球宣言如下
private LinearLayoutManager linearLayoutManager;
private int pastVisibleItems, visibleItemCount, totalItemCount;
private CustomRecyclerViewAdapter customRecyclerViewAdapter;
Run Code Online (Sandbox Code Playgroud)
首先,我在onCreate()方法内部创建了适配器实例,其中包含Empty Array并将其设置为recyclerView
linearLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(linearLayoutManager);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(
Utility.ItemDecorationConst);
recyclerView.addItemDecoration(dividerItemDecoration);
customRecyclerViewAdapter = new CustomRecyclerViewAdapter(getActivity());
recyclerView.setAdapter(customRecyclerViewAdapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
visibleItemCount = linearLayoutManager.getChildCount();
totalItemCount = linearLayoutManager.getItemCount();
pastVisibleItems = linearLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if ((visibleItemCount + pastVisibleItems) >= totalItemCount) {
loading = false;
customRecyclerViewAdapter.addProgressBarEntry();
controller.getNextPage(PublisherAppContainerFragment.this);
}
}
}
});
Run Code Online (Sandbox Code Playgroud)
渲染完成时查看我从中获取数据以AsyncTask进行填写recyclerView
我调用以下方法Adapter来填充数据
customRecyclerViewAdapter.addAll(myArray);
Run Code Online (Sandbox Code Playgroud)
注意:addAll()不是任何重写方法
以下是我的代码 CustomRecyclerViewAdapter
class CustomRecyclerViewAdapter extends RecyclerView.Adapter<CustomRecyclerViewAdapter.ViewHolder> {
ArrayList<MyModel> arrayList = new ArrayList<>();
Context context;
public CustomRecyclerViewAdapter(Context context) {
this.context = context;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ViewHolder viewHolder = null;
//inflated some view
return viewHolder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
//binded data to holder
}
@Override
public int getItemCount() {
return arrayList.size();
}
public void addAll(ArrayList myArray) {
this.arrayList.addAll(myArray)
}
public void clear() {
arrayList.clear();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public CardView cardView;
public ViewHolder(View view) {
super(view);
this.cardView = (CardView) view.findViewById(R.id.card_view);
this.cardView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
//handle operations
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以每当我从AsynTask我调用方法获取数据addAll()并且recyclerView像魅力一样工作.
现在,我的问题是它如何工作得很好,尽管我从来没有叫notifyDataSetChanged()上了adapter.是否有任何先前注册的适配器观察员?如果已返回的数据集public int getItemCount()已更改,谁会观察到?
正如我读到的那样 documentation
void notifyDataSetChanged()
通知任何已注册的观察员数据集已更改.
这意味着即使有一些observers注册,你需要notify使用它们notifyDataSetChanged().对?
我也打过电话
boolean flag = customRecyclerViewAdapter.hasObservers();
Run Code Online (Sandbox Code Playgroud)
要知道是否有任何观察员注册?Flag是True.
所以任何人都愿意帮助我理解这些东西究竟是如何运作的?
如果你查看 RecyclerView setAdapter 调用的源代码,你会发现一个方法setAdapterInternal(adapter, false, true);负责
将当前适配器替换为新适配器并触发侦听器。
此方法负责将旧适配器与新适配器交换,并且在内部它还注册自定义Data Observer。这就是您将标志设为true的原因
根据我对您的代码的了解,我想说您的代码中没有任何观察者RecyclerView正在获取更改并保持列表更新。更有可能的是,您只是“幸运”,因为当您滚动列表时,布局管理器不断调用getItemCount()适配器以确定是否应该显示更多项目。每当您调用 时addAll(),您都会默默地更新项目计数,而观察者恰好会收到有关更改的通知。
这绝对是一个错误,如果您依赖于特定观察者来监视列表的某些方面,或者做的不仅仅是将新项目附加到底部(例如更改或插入),您更有可能在实现中看到它的影响现有项目之间)。正如您所指出的,正确的实现是在列表更新时调用notifyDataSetChanged(),或者如果可以的话,最好更具体地说明更改的内容。例如,您可以使用:
public void addAll(ArrayList myArray) {
int positionStart = getItemCount() - 1;
this.arrayList.addAll(myArray);
notifyItemRangeInserted(positionStart, myArray.size());
}
public void clear() {
int oldSize = getItemCount();
arrayList.clear();
notifyItemRangeRemoved(0, oldSize);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5109 次 |
| 最近记录: |