【问题标题】:Issue with multiple Recyclerview inside ViewpagerViewpager 中多个 Recyclerview 的问题
【发布时间】:2018-12-21 12:40:26
【问题描述】:

我有一个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;
}

}

最后这是我在片段中使用的RecyclerViewadapter

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 中。

【问题讨论】:

  • 您在哪里以及如何向RecyclerViews 添加项目?

标签: android android-recyclerview android-viewpager


【解决方案1】:

基本区别

FragmentPagerAdapter

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

FragmentStatePagerAdapter

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

所以 FragmentPagerAdapter 会解决这个问题

我在视图寻呼机上调用 notifyDatasetChanged()。所以每次片段内的回收器视图都会重新初始化。

【讨论】:

    【解决方案2】:

    从 vew 寻呼机适配器类中删除覆盖函数“getItemPosition”。希望它会有所帮助。

    【讨论】:

      【解决方案3】:

      谢谢大家的解答,反正这个问题和RecyclerviewViewpager无关,是因为我对变量引用的误解。我在活动中的其他地方更改了ArrayList。这会影响recyclerview 中的列表。

      【讨论】:

        猜你喜欢
        • 2017-03-02
        • 1970-01-01
        • 2021-03-04
        • 2016-05-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多