Viewpager 中的多个 Recyclerview 问题

Issue with multiple Recyclerview inside Viewpager

我有一个 Viewpager,里面有两个标签。选项卡是卡片和收藏夹卡片。我在两个选项卡中使用相同的片段。该片段包含我动态更新的 RecyclerView 。我将元素一一添加到两个选项卡中。我首先将元素完全添加到第一个选项卡(卡片选项卡),完成后我将元素添加到第二个选项卡(收藏夹选项卡)。我的问题是当我将元素添加到第二个选项卡时,第一个选项卡中的 RecyclerView 也会更新。现在第一个选项卡中的元素 RecyclerView 是现有元素加上我在第二个选项卡中添加的元素的总和。我在 ViewPager 选项卡中设置了两个不同的 ArrayList。但是当 getItemCount() 在第一个选项卡 RecyclerView 中调用时,ArrayList 具有我在第二个选项卡中添加的元素。

我在两个选项卡中使用带有 RecyclerView 的相同片段。当我想更新单个选项卡时,我在 ViewPager 上调用 notifyDatasetChanged()。所以每次 RecyclerView 里面的片段都被重新初始化。

这是我的 Viewpager 适配器

public class ViewPagerWebCardsAdapter extends FragmentStatePagerAdapter {

private ArrayList<WebCardBaseResponseModel> webCardDetailList;
private ArrayList<WebCardBaseResponseModel> followingWebCardList;
private Context context;
private boolean isEmptyFavoriteWebcardList;
private boolean isEmptyWebcardsList;

public ViewPagerWebCardsAdapter(FragmentManager fm, ArrayList<WebCardBaseResponseModel> webCardDetailList,
                                ArrayList<WebCardBaseResponseModel> followingWebCardList,
                                Context context) {
    super(fm);
    this.webCardDetailList = webCardDetailList;
    this.followingWebCardList = followingWebCardList;
    this.context = context;
}

public void updateWebCardLists( ArrayList<WebCardBaseResponseModel> webCardDetailList,
                                ArrayList<WebCardBaseResponseModel> followingWebCardList) {
    this.webCardDetailList = webCardDetailList;
    this.followingWebCardList = followingWebCardList;
    notifyDataSetChanged();
}

public void setEmptyFollowingCardsFragment() {
    isEmptyFavoriteWebcardList = true;
    notifyDataSetChanged();
}

public void setEmptyWebCardsFragment() {
    isEmptyWebcardsList = true;
    notifyDataSetChanged();
}

@Override
public Fragment getItem(int position) {
    if(position == 0) {
        WebCardListFragment webCardListFragment = new WebCardListFragment();
        webCardListFragment.setWebCardDetailList(webCardDetailList);
        webCardListFragment.setEmptyListFragment(isEmptyWebcardsList);
        return webCardListFragment;
    } else {
        WebCardListFragment webCardListFragment = new WebCardListFragment();
        webCardListFragment.setWebCardDetailList(followingWebCardList);
        webCardListFragment.setEmptyListFragment(isEmptyFavoriteWebcardList);
        webCardListFragment.setAsFavoritesList();
        return webCardListFragment;
    }
}

@Override
public int getCount() {
    return Constants.NUMBER_TWO;
}

@Override
public int getItemPosition(Object object) {
    return POSITION_NONE;
}

@Override
public CharSequence getPageTitle(int position) {
    if(position == 0) {
        return context.getString(R.string.webcards);
    } else {
        return context.getString(R.string.favorite);
    }
}

}

这是我的卡片碎片

public class WebCardListFragment extends Fragment {

@BindView(R.id.web_card_recycler_view)
RecyclerView mWebCardDetailRecyclerView;

@BindView(R.id.tv_description)
TextView tvDescription;

@BindView(R.id.progress_bar)
public ProgressBar progressBar;

private WebCardListAdapter mWebCardListAdapter;
ArrayList<WebCardBaseResponseModel> mWebCardDetailList;
WebCardActivity activity;
private boolean isFavorites;
private boolean isEmptyListFragment;

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

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

public void setWebCardDetailList(ArrayList<WebCardBaseResponseModel> mWebCardDetailList) {
    this.mWebCardDetailList = mWebCardDetailList;
}

public void setAsFavoritesList() {
    this.isFavorites = true;
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_webcard_list, container, false);
    ButterKnife.bind(this, view);
    initView();

    return view;
}

private void initView() {
    if(isFavorites) {
        tvDescription.setText(getString(R.string.select_webcard_to_share));
    }

    RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(activity);
    mWebCardDetailRecyclerView.setLayoutManager(mLayoutManager);
    mWebCardDetailRecyclerView.setHasFixedSize(true);
    mWebCardDetailRecyclerView.setItemAnimator(new DefaultItemAnimator());
    if(mWebCardDetailList != null && mWebCardDetailList.size() > 0) {
        progressBar.setVisibility(View.GONE);
        tvDescription.setVisibility(View.VISIBLE);
        mWebCardListAdapter = new WebCardListAdapter(activity, mWebCardDetailList, isFavorites);
    }
    if(isEmptyListFragment) {
        progressBar.setVisibility(View.GONE);
        tvDescription.setVisibility(View.VISIBLE);
        tvDescription.setText(getString(R.string.no_webcards_to_list));
    }
    mWebCardDetailRecyclerView.setAdapter(mWebCardListAdapter);
}

public void setEmptyListFragment(boolean isEmptyList) {
    isEmptyListFragment = isEmptyList;
}

}

最后,这是我在片段中使用的 RecyclerView 适配器

public class WebCardListAdapter extends RecyclerView.Adapter<WebCardListAdapter.ViewHolder> {
private       Context                             mContext;
private       ArrayList<WebCardBaseResponseModel> mWebCardDetailList;
private boolean isFavorites;

public WebCardListAdapter(Context context, ArrayList<WebCardBaseResponseModel> webCardDetailList, boolean isFavorites) {
    mContext = context;
    mWebCardDetailList = webCardDetailList;
    this.isFavorites = isFavorites;
}

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

@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    setListItemView(holder, position);
    setListItemClickListener(holder);
}

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

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

@Override
public int getItemViewType(int position) {
    return position;
}

class ViewHolder extends RecyclerView.ViewHolder {
    private TextView     mCardNameTextView;
    private LinearLayout mWeCardLinearLayout;
    @BindView(R.id.tv_phone)
    TextView phone;

    ViewHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(this, itemView);
        mCardNameTextView = (TextView) itemView.findViewById(R.id.webcard_name_textview);
        mWeCardLinearLayout = (LinearLayout) itemView.findViewById(R.id.wed_card_title_linear_layout);
    }
}

}

我希望两个选项卡中的 ListView 是独立的。当我将元素添加到第二个选项卡 RecyclerView 时,这不应反映在第一个选项卡 RecyclerView.

基本区别

FragmentPagerAdapter

适用于数量有限(固定)的物品(碎片)。为什么?因为它永远不会从 FragmentManager 中删除一个片段实例,一旦它被创建(除非 Activity 完成)。它只会从当前不可见的片段中分离视图。 onDestroyView() 将在您的 Fragment 无法访问时调用,稍后 onCreateView() 将在您返回此 Fragment 时调用。

FragmentStatePagerAdapter

FragmentStatePagerAdapter 更精通内存。一旦无法访问,它就会从 FragmentManager 中完全删除 Fragment 实例。已移除片段的状态存储在 FragmentStatePagerAdapter 中。一旦您 return 回到现有项目并恢复状态,就会重新创建 Fragment 实例。此适配器适用于计数未知的列表或项目变化很大的列表。

所以 FragmentPagerAdapter 将解决这个问题

我在视图寻呼机上调用了 notifyDatasetChanged()。因此,每次重新初始化片段内的回收器视图时。

从寻呼机适配器 class 中删除覆盖功能 "getItemPosition"。希望对你有帮助。

谢谢解答,反正这个问题与RecyclerviewViewpager无关,是我对变量引用的误解造成的。我在 activity 内的其他地方更改了 ArrayList。这会影响 recyclerview.

中的列表