android - notifyDataSetChanged 不适用于 RecyclerView

标签 android android-5.0-lollipop android-recyclerview

我正在从服务器获取数据,然后对其进行解析并将其存储在列表中。我将此列表用于 RecyclerView 的适配器。我正在使用 fragment 。

我正在使用带有 KitKat 的 Nexus 5。我正在为此使用支持库。这会有所作为吗?

这是我的代码:(对问题使用虚拟数据)

成员变量:

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()

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\nBusinesses 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;
    }
}

但我没有得到 View 中显示的数据。我做错了什么?

这是我的日志,

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() 吗?

最佳答案

在您的 parseResponse() 中,您正在创建 BusinessAdapter 类的新实例,但实际上您并没有在任何地方使用它,因此您的 RecyclerView 不知道新实例存在。

您需要:

  • 再次调用 recyclerView.setAdapter(mBusinessAdapter) 以更新 RecyclerView 的适配器引用以指向您的新适配器
  • 或者只是删除 mBusinessAdapter = new BusinessAdapter(mBusinesses); 以继续使用现有的适配器。由于您尚未更改 mBusinesses 引用,因此适配器仍将使用该数组列表,并且在您调用 notifyDataSetChanged() 时应正确更新。

关于android - notifyDataSetChanged 不适用于 RecyclerView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24740557/

相关文章:

android - 在滚动的 recyclerview cardview 进入一页

android - 在 phonegap/cordova 中显示保存在存储目录(data/data/yourapp/folder)中的图像

java - 布局中的 Eclipse ADT Open 声明不再默认

java - 如何从文档中检索嵌套对象并将其显示在 FirestoreRecyclerOptions 中?

android - lollipop android 5.0.1 samsung 上的 native 崩溃/system/lib/libart.so

java - 无法使用新列表更新 Recyclerview 适配器,新列表显示空白

java - 按下按钮的 Android Firebase RecyclerView 出现无法解释的错误

java - Android:TabLayout如何以编程方式设置height = 0?

android - RecyclerView 列表结束监听器

android - 在 Android 5.0 中通过 NFC 激活设备所有者期间无法连接 Wifi