notifyDataSetChanged 不更新我的回收站视图

notifyDataSetChanged does not update my recycler view

我有一个 ArrayListIntentService 获取数据。获得数据后,我更新了我的适配器并调用了 notifyDataSetChanged()。但它不会改变数据。

这是我的代码:

public class Nearby_ViewPager_Stations extends Fragment {

private View mRootView = null;
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private StationsReceiver mStationsReciever;
private MKLoader mProgressBar;

private RecyclerView.Adapter mAdapter;
private Context mContext;
ArrayList<ArrayList<StationArrivalPOJO>> stationArrivalPOJO = new ArrayList<>();

private static final String TAG = "NearbyViewPagerStations";

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    mContext = context;
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    if (mRootView == null) {
        mRootView = inflater.inflate(R.layout.nearby_viewpager_stations, container, false);
        mRecyclerView = (RecyclerView) mRootView.findViewById(R.id.recycler_view);
        mProgressBar = (MKLoader) mRootView.findViewById(R.id.progressBar);
    }

    mStationsReciever = new StationsReceiver(new Handler());
    mLayoutManager = new LinearLayoutManager(mContext);
    mRecyclerView.setLayoutManager(mLayoutManager);
    mAdapter = new Adapter_recyclerView(stationArrivalPOJO);
    mRecyclerView.setAdapter(mAdapter);

    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            startIntentService();
            handler.postDelayed(this, 20*1000);
        }
    }, 1000);
    return mRootView;
}

private void startIntentService() {
    Intent intent1 = new Intent(mContext, GetAllStationsAndStopsIntentService.class);
    intent1.putExtra("Receiver", mStationsReciever);
    intent1.putExtra("latitude", Constants.latitude);
    intent1.putExtra("longitude", Constants.longitude);
    mContext.startService(intent1);
}

void addAdapter(ArrayList<ArrayList<StationArrivalPOJO>> resultData) {
    mProgressBar.setVisibility(View.GONE);

    if (stationArrivalPOJO.size() > 0)
        stationArrivalPOJO.clear();
    stationArrivalPOJO.addAll(resultData);
    mAdapter.notifyDataSetChanged();

    Log.v(TAG, "added all data: "+ stationArrivalPOJO.get(0).get(0).getTimeToStation());
}

public class StationsReceiver extends ResultReceiver {
    StationsReceiver(Handler handler) {
        super(handler);
    }

    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        super.onReceiveResult(resultCode, resultData);

        addAdapter((ArrayList<ArrayList<StationArrivalPOJO>>)resultData.getSerializable("StationPOJO"));
    }
}

}

这是我的适配器代码:

 class Adapter_recyclerView extends RecyclerView.Adapter {

private ArrayList<ArrayList<StationArrivalPOJO>> mStationPojoList;
private LinearLayout mLinearLayout;

private Context mContext;

private static final String TAG = "AdapterRecyclerView";

Adapter_recyclerView(ArrayList<ArrayList<StationArrivalPOJO>> data) {
    mStationPojoList = data;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    ((ViewHolder)holder).stationNameTV.setText(mStationPojoList.get(position).get(0).getStationName());

    ArrayList<String> mUniqueStationName = new ArrayList<>();  //Unique platform names of a station got from hash set 'uniqStatNames'
    HashSet<String> uniqStatNames = new HashSet<>(); //Unique platform names of a station

    for (int i = 0;i<mStationPojoList.get(position).size(); i++) {
        uniqStatNames.add(mStationPojoList.get(position).get(i).getPlatformName()
        + mStationPojoList.get(position).get(i).getTowards());
    }

    for(Iterator<String> it = uniqStatNames.iterator() ; it.hasNext() ; ) {
        mUniqueStationName.add(it.next());
    }

    for (int j=0; j<mUniqueStationName.size(); j++) {
        ArrayList<StationArrivalPOJO> arrivalPOJOs = new ArrayList<>();   //Platform wise categorized train details
        for (int i = 0;i<mStationPojoList.get(position).size(); i++) {
            if (mUniqueStationName.get(j).contains(mStationPojoList.get(position).get(i).getPlatformName())
                    && mUniqueStationName.get(j).contains(mStationPojoList.get(position).get(i).getTowards())) {
                arrivalPOJOs.add(mStationPojoList.get(position).get(i));
            }
        }

        Collections.sort(arrivalPOJOs, new Comparator<StationArrivalPOJO>() {
            @Override
            public int compare(StationArrivalPOJO stationArrivalPOJO, StationArrivalPOJO t1) {
                return stationArrivalPOJO.getTimeToStation() - t1.getTimeToStation();
            }
        });

        for (int k=0; k<arrivalPOJOs.size(); k++) {
        Log.v(TAG, j+":"+mUniqueStationName.size()+"boo"+arrivalPOJOs.toString());
        Log.v(TAG, "boom " + arrivalPOJOs.get(k).getPlatformName() + ":" + arrivalPOJOs.get(k).getTowards());

        RelativeLayout relativeLayout = new RelativeLayout(mContext);
        relativeLayout.setPadding(16, 16, 16, 16);
        LinearLayout linearLayout = new LinearLayout(mContext);
        linearLayout.setOrientation(LinearLayout.VERTICAL);

        TextView trainName = new TextView(mContext);
        trainName.setText(arrivalPOJOs.get(k).getPlatformName());

        TextView towards = new TextView(mContext);
        towards.setText(arrivalPOJOs.get(k).getTowards());

        linearLayout.addView(trainName);
        linearLayout.addView(towards);

        RelativeLayout.LayoutParams layoutParams1 = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        layoutParams1.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
        linearLayout.setLayoutParams(layoutParams1);

        TextView time = new TextView(mContext);
        time.setText(String.valueOf(arrivalPOJOs.get(k).getTimeToStation()));

        RelativeLayout.LayoutParams layoutParams2 = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        layoutParams2.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
        time.setLayoutParams(layoutParams2);

        relativeLayout.addView(linearLayout);
        relativeLayout.addView(time);

        mLinearLayout.addView(relativeLayout);
        }}
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View rootView =  LayoutInflater.from(parent.getContext())
            .inflate(R.layout.adapter_recyclerview,parent,false);
    mContext = parent.getContext();

    mLinearLayout = (LinearLayout) rootView.findViewById(R.id.cardViewLinearLayout);
    TextView mStationName = (TextView) rootView.findViewById(R.id.stationName);

    return new ViewHolder(rootView, mStationName);
}

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

private static class ViewHolder extends RecyclerView.ViewHolder {
    TextView stationNameTV;

    ViewHolder(View view, TextView stationNameTV) {
        super(view);
        this.stationNameTV = stationNameTV;
    }
}

}

当我从 ArrayList 检索数据并在日志站中打印时,我得到了更新的值。但是这些更新并没有反映在我的回收站列表中。

我在 Stack Overflow 中看到其他问题说:

  1. 我们需要来自同一个 Fragment 对象的更新数据

  2. notifyDataSetChanged()` 应该从 ui 线程调用。

我不明白我错过了什么。

您不需要再次设置适配器来更新元素。

相反,您应该调用 notifyDataSetChanged(),但您必须先更新适配器的数据,这是一个很好的方法:

1-

将此方法添加到您的适配器

public void updateData(final ArrayList<ArrayList<StationArrivalPOJO>> stationArrivalPOJO ) {
        mStationPojoList= new ArrayList<>();
        mStationPojoList.addAll(stationArrivalPOJO);
    }

2-

在您的 Nearby_ViewPager_StationsaddAdapter,执行以下操作:

  stationArrivalPOJO.addAll(resultData);
  mAdapter.updateData(stationArrivalPOJO); // updating adapter's data
  mAdapter.notifyDataSetChanged(); //notifying the adapter

TL;DR:不要将适配器存放在 activity/fragment 的 属性 中。始终从 mRecyclerView.getAdapter()

调用和转换

我遇到了同样的问题。
所有人只说使用 notifyDataSetChanged() 并且应该这样做(有些人可能会争论使用 notifyItem* 那些,我会说这取决于)

由于您对已接受答案的评论(即使不是正确的答案),刚刚修复了它

是的,正在我的适配器上调用 notifyDataSetChanged(),但不是要更新的正确适配器。
我有一个回收站,过滤了大约 500 个项目,我可以看到新项目列表正在减少到 10 个项目,但 UI 仍然显示所有项目。
让我怀疑我的是否被调用,所以我放了一些日志,好吧,我看到它仍在使用原来的 500 项列表,即使我得到日志表明适配器有一个只有 10 项的新列表.

好吧,这是由于我的片段中有一个 属性 并更新了该适配器造成的。

private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;

onCreateView() {
    // Retrieve data and more code
    mRecyclerView = view.findViewById(R.id.recycler_view);
    mAdapter = new MyRecyclerViewAdapter(data);
    mRecyclerView.setAdapter(mAdapter);
}

filter(String txt) {
    // Here the adapter handles filtering the list
    // and calling notifyDataSetChanged()
    mAdapter.filter(query);
}

现在是这样的,正在运行

private RecyclerView mRecyclerView;

onCreateView() {
    // Retrieve data and more code
    mRecyclerView = view.findViewById(R.id.recycler_view);
    mRecyclerView.setAdapter(new MyRecyclerViewAdapter(data));
}

filter(String txt) {
    // Here the adapter handles filtering the list
    // and calling notifyDataSetChanged()
    ((MyRecyclerViewAdapter)mRecyclerView.getAdapter()).filter(query)
}

我会说,如果答案没有帮助解决您的问题,您不必接受它。
如果你自己解决了它,你可以回答你自己的问题并接受你自己的答案。