notifyDataSetChanged 不适用于 RecyclerView [英] notifyDataSetChanged not working on RecyclerView
问题描述
我从服务器获取数据,然后解析它并将其存储在一个列表中.我将此列表用于 RecyclerView 的适配器.我正在使用片段.
I am getting data from server and then parsing it and storing it in a List. I am using this list for the RecyclerView's adapter. I am using Fragments.
我正在使用带有 KitKat 的 Nexus 5.我正在为此使用支持库.这会有所作为吗?
I am using a Nexus 5 with KitKat. I am using support library for this. Will this make a difference?
这是我的代码:(对问题使用虚拟数据)
Here is my code: (Using dummy data for the question)
成员变量:
List<Business> mBusinesses = new ArrayList<Business>();
RecyclerView recyclerView;
RecyclerView.LayoutManager mLayoutManager;
BusinessAdapter mBusinessAdapter;
我的onCreateView()
:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Getting data from server
getBusinessesDataFromServer();
View view = inflater.inflate(R.layout.fragment_business_list,
container, false);
recyclerView = (RecyclerView) view
.findViewById(R.id.business_recycler_view);
recyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(mLayoutManager);
mBusinessAdapter = new BusinessAdapter(mBusinesses);
recyclerView.setAdapter(mBusinessAdapter);
return view;
}
从服务器获取数据后,调用parseResponse()
.
After getting data from server, parseResponse()
is called.
protected void parseResponse(JSONArray response, String url) {
// insert dummy data for demo
mBusinesses.clear();
Business business;
business = new Business();
business.setName("Google");
business.setDescription("Google HeadQuaters");
mBusinesses.add(business);
business = new Business();
business.setName("Yahoo");
business.setDescription("Yahoo HeadQuaters");
mBusinesses.add(business);
business = new Business();
business.setName("Microsoft");
business.setDescription("Microsoft HeadQuaters");
mBusinesses.add(business);
Log.d(Const.DEBUG, "Dummy Data Inserted
Businesses Length: "
+ mBusinesses.size());
mBusinessAdapter = new BusinessAdapter(mBusinesses);
mBusinessAdapter.notifyDataSetChanged();
}
我的业务适配器:
public class BusinessAdapter extends
RecyclerView.Adapter<BusinessAdapter.ViewHolder> {
private List<Business> mBusinesses = new ArrayList<Business>();
// Provide a reference to the type of views that you are using
// (custom viewholder)
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mTextViewName;
public TextView mTextViewDescription;
public ImageView mImageViewLogo;
public ViewHolder(View v) {
super(v);
mTextViewName = (TextView) v
.findViewById(R.id.textView_company_name);
mTextViewDescription = (TextView) v
.findViewById(R.id.textView_company_description);
mImageViewLogo = (ImageView) v
.findViewById(R.id.imageView_company_logo);
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public BusinessAdapter(List<Business> myBusinesses) {
Log.d(Const.DEBUG, "BusinessAdapter -> constructor");
mBusinesses = myBusinesses;
}
// Create new views (invoked by the layout manager)
@Override
public BusinessAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
Log.d(Const.DEBUG, "BusinessAdapter -> onCreateViewHolder()");
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.item_business_list, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
Log.d(Const.DEBUG, "BusinessAdapter -> onBindViewHolder()");
Business item = mBusinesses.get(position);
holder.mTextViewName.setText(item.getName());
holder.mTextViewDescription.setText(item.getDescription());
holder.mImageViewLogo.setImageResource(R.drawable.ic_launcher);
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
Log.d(Const.DEBUG, "BusinessAdapter -> getItemCount()");
if (mBusinesses != null) {
Log.d(Const.DEBUG, "mBusinesses Count: " + mBusinesses.size());
return mBusinesses.size();
}
return 0;
}
}
但是我没有在视图中显示数据.我做错了什么?
But I don't get the data displayed in the view. What am I doing wrong?
这是我的日志,
07-14 21:15:35.669: D/xxx(2259): Dummy Data Inserted
07-14 21:15:35.669: D/xxx(2259): Businesses Length: 3
07-14 21:26:26.969: D/xxx(2732): BusinessAdapter -> constructor
此后我没有收到任何日志.不应该再次调用适配器中的 getItemCount()
吗?
I don't get any logs after this. Shouldn't getItemCount()
in adapter should be called again?
推荐答案
在您的 parseResponse()
中,您正在创建 BusinessAdapter
类的新实例,但您没有实际上并没有在任何地方使用它,因此您的 RecyclerView
不知道新实例存在.
In your parseResponse()
you are creating a new instance of the BusinessAdapter
class, but you aren't actually using it anywhere, so your RecyclerView
doesn't know the new instance exists.
您要么需要:
- 再次调用
recyclerView.setAdapter(mBusinessAdapter)
以更新 RecyclerView 的适配器引用以指向新的引用 - 或者只是删除
mBusinessAdapter = new BusinessAdapter(mBusinesses);
以继续使用现有的适配器.由于您尚未更改mBusinesses
引用,因此适配器仍将使用该数组列表,并且在您调用notifyDataSetChanged()
时应正确更新.
- Call
recyclerView.setAdapter(mBusinessAdapter)
again to update the RecyclerView's adapter reference to point to your new one - Or just remove
mBusinessAdapter = new BusinessAdapter(mBusinesses);
to continue using the existing adapter. Since you haven't changed themBusinesses
reference, the adapter will still use that array list and should update correctly when you callnotifyDataSetChanged()
.
这篇关于notifyDataSetChanged 不适用于 RecyclerView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!