首页 > 解决方案 > 为什么 RecylerView.notifyDataSetChanged() 添加导航组件后停止工作?

问题描述

我从 Android Jetpack 实现了导航,然后我的应用程序中的所有 RecyclerViews 在数据更改后停止更新。在调试模式下,我看到数据确实发生了变化并被notifyDataSetChanged()调用,但 RVs 实际上没有更新(没有添加新项目)。

我尝试过使用其他方法,例如notifyItemInserted()等等。试图通知外面的适配器。没有什么帮助。

分段:

...
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                         @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.profnastil_fragment, container, false);
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    ...
    ImageButton addRoofBtn = view.findViewById(R.id.roof_add_btn);
    addRoofBtn.setOnClickListener(v -> {
        ...
        Square roof = new Square(width, height);
        mViewModel.addRoof(roof);
    });
    mViewModel = ViewModelProviders.of(this).get(ProfnastilViewModel.class);
    mProfnastilAdapter = new SquaresAdapter(mViewModel, SquaresAdapter.SQUARE_TYPE_ROOF);
    RecyclerView roofRv = view.findViewById(R.id.roof_list);
    RecyclerView.LayoutManager wallsLayoutManager = new LinearLayoutManager(getContext());
    roofRv.setLayoutManager(wallsLayoutManager);
    roofRv.setHasFixedSize(true);
    roofRv.setAdapter(mProfnastilAdapter);
    mViewModel.getRoofs().observe(this, roofs -> mProfnastilAdapter.setSquares(roofs));
}

适配器:

...
public SquaresAdapter(SquareViewModelBase model, String squareType) {
    mModel = model;
    mSquares = new ArrayList<>();
    setHasStableIds(true);
    mSquareType = squareType;
}

public static class SquareHolder extends RecyclerView.ViewHolder {
    View view;
    TextView heightText;
    TextView widthText;
    TextView squareText;

    private SquareHolder(@NonNull View itemView) {
        super(itemView);
        view = itemView;
        heightText = itemView.findViewById(R.id.square_height);
        widthText = itemView.findViewById(R.id.square_width);
        squareText = itemView.findViewById(R.id.result_square);
    }
}

@Override
public int getItemCount() {
    if (mSquares == null) return 0;
    return mSquares.size();
}

@Override
public long getItemId(int position) {
    return position;
}

@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.item_square, parent, false);
    return new SquareHolder(itemView);
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, final int position) {
    final Square square = mSquares.get(position);
    SquareHolder vh = (SquareHolder) viewHolder;
    vh.heightText.setText(StringUtils.format(square.getHeight()));
    vh.widthText.setText(StringUtils.format(square.getWidth()));
    vh.squareText.setText(StringUtils.format(square.getSquare()));
    vh.view.findViewById(R.id.item_del_btn).setOnClickListener(v -> {
        mModel.removeSquare(square, mSquareType);
    });
}

public void setSquares(List<Square> newSquares) {
    mSquares.clear();
    mSquares.addAll(newSquares);
    notifyDataSetChanged();
}

视图模型:

...
private MutableLiveData<List<Square>> mRoofs = new MutableLiveData<>();
public void addRoof(Square roof) {
    List<Square> roofs = mRoofs.getValue();
    if (roofs == null) roofs = new ArrayList<>();
    roofs.add(roof);
    mRoofs.setValue(roofs);
}

在我实施导航图之前,一切正常。会发生什么以及如何使其发挥作用?

标签: androidandroid-recyclerview

解决方案


最后view.requireLayout() 在 Fragment 添加帮助了我:

mViewModel.getRoofs().observe(this, roofs -> {
    mProfnastilAdapter.setSquares(roofs));
    view.requireLayout();
};

但我仍然不明白发生了什么以及为什么它对我有帮助 =) 如果有人向我解释,我将不胜感激。


推荐阅读