Проблема с несколькими Recyclerview внутри Viewpager - PullRequest
0 голосов
/ 21 декабря 2018

У меня есть Viewpager с двумя вкладками внутри.На вкладках «Карты» и «Любимые карты».Я использую один и тот же фрагмент внутри обеих вкладок.Фрагмент содержит RecyclerView, который я обновляю динамически.Я добавляю элементы на обе вкладки одну за другой.Сначала я полностью добавляю элементы на первую вкладку (вкладка «Карты»), после чего добавляю элементы на вторую вкладку (вкладка «Любимая карта»).Моя проблема в том, что когда я добавляю элементы на вторую вкладку, моя RecyclerView внутри первой вкладки также обновляется.Теперь элементы на первой вкладке RecyclerView - это сумма существующих элементов плюс элементы, которые я добавляю на второй вкладке.Я установил два разных ArrayList на вкладке ViewPager.Но когда getItemCount() вызывается на первой вкладке RecyclerView, ArrayList содержит элемент, который я добавил на второй вкладке.

Я использую один и тот же фрагмент с RecyclerView на обеих вкладках.Когда я хочу обновить одну вкладку, я звоню notifyDatasetChanged() на ViewPager.Поэтому каждый раз 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.

Ответы [ 3 ]

0 голосов
/ 21 декабря 2018

Удалите функцию переопределения "getItemPosition" из класса адаптера пейджера vew.Надеюсь, это поможет.

0 голосов
/ 24 декабря 2018

Спасибо за ответы, в любом случае эта проблема не имеет ничего общего с Recyclerview или Viewpager, это произошло из-за моего недопонимания относительно ссылки на переменную.Я изменяю ArrayList где-то еще внутри активности.Это влияет на список в recyclerview.

0 голосов
/ 21 декабря 2018

Основная разница

FragmentPagerAdapter

Подходит для ограниченного (фиксированного) количества элементов (фрагментов).Зачем?Потому что он никогда не удаляет экземпляр фрагмента из FragmentManager после его создания (если только это действие не завершено).Это только отделяет Представления от Фрагментов, которые в настоящее время не видимы.onDestroyView () будет вызываться для вашего фрагмента, как только он окажется вне досягаемости, а затем будет вызываться onCreateView (), когда вы вернетесь к этому фрагменту.

FragmentStatePagerAdapter

AFragmentStatePagerAdapter более удобен в использовании памяти.Он полностью удаляет экземпляры фрагмента из FragmentManager, когда они находятся вне досягаемости.Состояние удаленных фрагментов хранится внутри FragmentStatePagerAdapter.Экземпляр Fragment воссоздается, как только вы вернетесь к существующему элементу, и состояние будет восстановлено.Этот адаптер подходит для списков с неизвестным количеством или для списков, в которых элементы сильно меняются.

Поэтому FragmentPagerAdapter решит эту проблему

Я вызываю notifyDatasetChanged () на пейджере представления.Таким образом, каждый раз вид рециркулятора внутри фрагмента повторно инициализируется.

...