Когда срабатывает наблюдатель в plannerFragment, вкладка обновляется. Это приводит к тому, что представление recyclerview в localeChoosingFragment сбрасывается в первую позицию. В качестве обходного пути я попытался использовать обработчик для автоматической прокрутки представления recyclerview в нужное место (согласно ViewModel), но я смущен и обеспокоен тем, почему это происходит. Перед использованием ViewPager2 я добавил оба (localeChoosingFragment и localeExploringFragment) в макет кадра вручную и попробовал показать/скрыть и прикрепить/отсоединить, но возникла та же проблема (сброс представления recyclerview в первую позицию).
Кто-нибудь знает, почему так может быть? Это кажется мелочью, но я обеспокоен тем, что происходит что-то, о чем я не знаю и о чем должен знать, особенно на этой ранней стадии проекта.
Recyclerview не воссоздается, и и notifyDataSet не изменился.
Этот ViewPager 2 на самом деле является частью фрагмента, выбранного из другого ViewPager 2, но я не думаю, что это вызывает проблему.Я приложу очищенную версию своего кода.
Вот планировщик:
Код: Выделить всё
public class PlannerFragment extends Fragment {
Context mContext;
JapanGuideViewModel japanGuideViewModel;
View plannerFragmentView;
ViewPager2 plannerFragmentViewPager2;
TabLayout tabLayout;
public static final String TAG = "JapanGuideTAG";
public PlannerFragment() {
Toast.makeText(mContext, "New Planner Fragment, empty constructor", Toast.LENGTH_SHORT).show();
}
public PlannerFragment(Context mContext, JapanGuideViewModel japanGuideViewModel) {
this.japanGuideViewModel = japanGuideViewModel;
this.mContext = mContext;
Log.d(TAG, "New Planner Fragment, arguments passed");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "oncreate in planner fragment");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(TAG, "oncreateview in planner fragment");
plannerFragmentView = inflater.inflate(R.layout.fragment_planner, container, false);
return plannerFragmentView;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.d(TAG, "onViewCreated in PlannerFragment");
plannerFragmentViewPager2 = plannerFragmentView.findViewById(R.id.plannerFragmentViewPager2);
tabLayout = plannerFragmentView.findViewById(R.id.plannerFragmentTabLayout);
PlannerFragmentViewPager2Adaptor plannerFragmentViewPager2Adaptor = new PlannerFragmentViewPager2Adaptor(getChildFragmentManager(), getLifecycle(), mContext, japanGuideViewModel);
plannerFragmentViewPager2.setAdapter(plannerFragmentViewPager2Adaptor);
plannerFragmentViewPager2.setUserInputEnabled(false);
TabLayoutMediator.TabConfigurationStrategy tabConfigurationStrategy = new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
Log.d(TAG, "onConfigure in tabConfigurationStrategy");
if (position == 0) {
Log.d(TAG, "Chooser");
tab.setText("Explore Prefectures");
} else if (position == 1) {
tab.setText("Explore Chosen Prefecture");
}
}
};
Log.d(TAG, "attachingTabLayoutMediator");
new TabLayoutMediator(tabLayout, plannerFragmentViewPager2, tabConfigurationStrategy).attach();
Observer dataDownloadedObserver = new Observer() {
@Override
public void onChanged(Object o) {
if (japanGuideViewModel.getDataDownloaded().getValue() > 0) {
Log.d(TAG, "onChanged called in data downloaded observer. Value is " + japanGuideViewModel.getDataDownloaded().getValue());
japanGuideViewModel.getCurrentLocaleBeingViewed().setValue(0);
}
}
};
Observer localeToExploreChangedObserver = new Observer() {
@Override
public void onChanged(Object o) {
Log.d(TAG, "localeChangedObserver in planner fragment");
TabLayout.Tab tab = tabLayout.getTabAt(1);
if (tab != null) {
Log.d(TAG, "the tab is" + tab.getPosition());
// THIS IS WHERE THE PROBLEM OCCURS.
// If this line (setting the text) is removed, the recyclerview in
// localeChoosingFragment does not reset to the first position.
tab.setText(japanGuideViewModel.getLocaleNamesArray().getValue().get(japanGuideViewModel.getCurrentLocaleBeingViewed().getValue()));
}
}
};
japanGuideViewModel.getCurrentLocaleBeingViewed().observe(getViewLifecycleOwner(), localeToExploreChangedObserver);
japanGuideViewModel.getDataDownloaded().observe(getViewLifecycleOwner(), dataDownloadedObserver);
} //onViewCreated
public class PlannerFragmentViewPager2Adaptor extends FragmentStateAdapter {
Context mContext;
JapanGuideViewModel japanGuideViewModel;
public PlannerFragmentViewPager2Adaptor(FragmentManager fragmentManager, Lifecycle lifecycle, Context mContext, JapanGuideViewModel japanGuideViewModel) {
super(fragmentManager, lifecycle);
this.japanGuideViewModel = japanGuideViewModel;
this.mContext = mContext;
Log.d(TAG, "full constructor in planner fragment");
}
@NonNull
@Override
public Fragment createFragment(int position) {
Log.d(TAG, "createFragment called in plannerFragment. Position is ");
switch (position) {
case 0:
Log.d(TAG, "planner fragment, case 0, localechoosingfragment");
LocaleChoosingFragment localeChoosingFragment = new LocaleChoosingFragment(mContext, japanGuideViewModel);
return localeChoosingFragment;
case 1:
Log.d("planner fragment localeExploringFragmentTAG", "case 1");
LocaleExploringFragment localeExploringFragment = new LocaleExploringFragment(mContext, japanGuideViewModel);
return localeExploringFragment;
default:
Log.d(TAG, "default constructor so returning localeChoosingFragment");
localeChoosingFragment = new LocaleChoosingFragment(mContext, japanGuideViewModel);
return localeChoosingFragment;
}
}
@Override
public int getItemCount() {
return 2;
}
}
}
Код: Выделить всё
public class LocaleChoosingFragment extends Fragment {
JapanGuideViewModel japanGuideViewModel;
Context mContext;
View localeChoosingFragmentView;
public static final String TAG = "JapanGuideTAG";
RecyclerView localeChoosingRecyclerView;
LinearLayoutManager recyclerViewLayoutManager;
LocaleChoosingRecyclerViewAdaptor localeChoosingAdaptor;
SnapHelperOneByOne SnapHelper;
public LocaleChoosingFragment() {
Log.d(TAG, "EMPTY constructor called for localeChoosingFragment");
}
public LocaleChoosingFragment(Context mContext, JapanGuideViewModel japanGuideViewModel) {
this.japanGuideViewModel = japanGuideViewModel;
this.mContext = mContext;
Log.d(TAG, "constructor called for localeChoosingFragment");
Toast.makeText(mContext, "Creating a new localeChoosingFragment", Toast.LENGTH_SHORT).show();
}
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate in localeChoosingFragment");
super.onCreate(savedInstanceState);
Log.d(TAG, "creating a NEW LOCALECHOOSING RECYCLERVIEW");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
Log.d(TAG, "onCreateView called in LocalChoosingFragment");
localeChoosingFragmentView = inflater.inflate(R.layout.fragment_locale_choosing, container, false);
localeChoosingRecyclerView = localeChoosingFragmentView.findViewById(R.id.localeChoosingRecyclerView);
return localeChoosingFragmentView;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.d(TAG, "onviewcreated in locale choosing fragment.");
localeChoosingAdaptor = new LocaleChoosingRecyclerViewAdaptor(mContext, japanGuideViewModel);
SnapHelper = new SnapHelperOneByOne();
recyclerViewLayoutManager = new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false);
localeChoosingRecyclerView.setLayoutManager(recyclerViewLayoutManager);
localeChoosingRecyclerView.setAdapter(localeChoosingAdaptor);
SnapHelper.attachToRecyclerView(localeChoosingRecyclerView);
// localeChoosingRecyclerView.scrollToPosition(japanGuideViewModel.getCurrentLocaleBeingViewed().getValue());
}
public class LocaleChoosingRecyclerViewAdaptor extends RecyclerView.Adapter {
Context mContext;
JapanGuideViewModel japanGuideViewModel;
Button exploreNowButton;
Button wontGoHereButton;
TextView localeNameTextView;
TextView localeDescriptionTextView;
ImageView localePhotoImageView;
TextView localePhotoCaptionTextView;
public LocaleChoosingRecyclerViewAdaptor() {
Log.d(TAG, "localeChoosingAdaptor created with empty constructor");
}
public LocaleChoosingRecyclerViewAdaptor(Context mContext, JapanGuideViewModel japanGuideViewModel) {
this.mContext = mContext;
this.japanGuideViewModel = japanGuideViewModel;
Log.d(TAG, "localeChoosingAdaptor created with full constructor");
}
@NonNull
@Override
public LocaleChoosingAdaptorHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Log.d(TAG, "oncreateviewholder in localechoosingfragment");
View view = LayoutInflater.from(mContext).inflate(R.layout.locale_recyclerview_holder, parent, false);
return new LocaleChoosingAdaptorHolder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder called in localeChoosingFragment. The position is " + position + " and the total size is " + getItemCount());
localeNameTextView = holder.itemView.findViewById(R.id.localeRecyclerviewHolderHeadingTextview);
localeNameTextView.setText(japanGuideViewModel.getLocalesDetailsArray().getValue().get(position).getLocaleName());
localeDescriptionTextView = holder.itemView.findViewById(R.id.localeRecyclerviewHolderDescriptionTextView);
if (japanGuideViewModel.getLocalesDetailsArray().getValue().get(holder.getAdapterPosition()).getLocaleDescription() != null) {
localeDescriptionTextView.setText(japanGuideViewModel.getLocalesDetailsArray().getValue().get(holder.getAdapterPosition()).getLocaleDescription());
}
localePhotoImageView = holder.itemView.findViewById(R.id.localeRecyclerviewHolderImageView);
if ((japanGuideViewModel.getLocalesDetailsArray().getValue().get(holder.getAdapterPosition()).getPhotoSet().size() != 0)) {
if ((japanGuideViewModel.getLocalesDetailsArray().getValue().get(holder.getAdapterPosition()).getPhotoSet().get(0).getURL() != null) && (!(japanGuideViewModel.getLocalesDetailsArray().getValue().get(holder.getAdapterPosition()).getPhotoSet().get(0).getURL().equals("")))) {
Glide.with(mContext).load(japanGuideViewModel.getLocalesDetailsArray().getValue().get(holder.getAdapterPosition()).getPhotoSet().get(0).getURL()).into(localePhotoImageView);
}
localePhotoCaptionTextView = holder.itemView.findViewById(R.id.localeRecyclerviewHolderPhotoCaptionTextView);
if ((japanGuideViewModel.getLocalesDetailsArray().getValue().get(holder.getAdapterPosition()).getPhotoSet().get(0).getCaption() != null) && (japanGuideViewModel.getLocalesDetailsArray().getValue().get(holder.getAdapterPosition()).getPhotoSet().get(0).getCaption() != "")) {
localePhotoCaptionTextView.setText(japanGuideViewModel.getLocalesDetailsArray().getValue().get(holder.getAdapterPosition()).getPhotoSet().get(0).getCaption());
}
}
exploreNowButton = holder.itemView.findViewById(R.id.LocaleRecyclerviewHolderExploreNowButton);
wontGoHereButton = holder.itemView.findViewById(R.id.LocaleRecyclerviewHolderWontGoHereButton);
exploreNowButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "Explore now button clicked. Setting the locale to explore to " + japanGuideViewModel.getCurrentLocaleBeingViewed().getValue());
japanGuideViewModel.getCurrentLocaleBeingViewed().setValue(holder.getAdapterPosition());
}
});
} //bind
@Override
public int getItemCount() {
return japanGuideViewModel.getLocalesDetailsArray().getValue().size();
}
} //recyclerview adaptor
public class LocaleChoosingAdaptorHolder extends RecyclerView.ViewHolder {
TextView localeNameTextView;
TextView localeDescriptionTextView;
Button exploreNowButton;
Button wontGoHereButton;
public LocaleChoosingAdaptorHolder(@NonNull View itemView) {
super(itemView);
Log.d(TAG, "localechoosing recyclerview holder constructor called");
localeNameTextView = itemView.findViewById(R.id.localeRecyclerviewHolderHeadingTextview);
localeDescriptionTextView = itemView.findViewById(R.id.localeRecyclerviewHolderDescriptionTextView);
exploreNowButton = itemView.findViewById(R.id.LocaleRecyclerviewHolderExploreNowButton);
wontGoHereButton = itemView.findViewById(R.id.LocaleRecyclerviewHolderWontGoHereButton);
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/782 ... ab-updated