RecyclerView в сбросе фрагмента с обновленной вкладкой ViewPagerJAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 RecyclerView в сбросе фрагмента с обновленной вкладкой ViewPager

Сообщение Anonymous »

У меня есть ViewPager 2 внутри plannerFragment, который вызывает 2 фрагмента: один (localeChoosingFragment) содержит recyclerview, позволяющий пользователю выбирать языковой стандарт, а другой — для выбора мест в этом языковом стандарте (localeExploringFragment). ViewModel (japanGuideViewModel) хранит данные (как MutableLiveData), включая int currentLocaleBeingViewed. Когда пользователь выбирает языковой стандарт, он обновляется, и наблюдатель в plannerFragment вызывает обновление одной из вкладок в PlannerFragment именем этого языкового стандарта. При нажатии на эту вкладку загружается localeExploringFragment для этой локали.
Когда срабатывает наблюдатель в 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;
}
}
}
А вот localeChoosingFragment:

Код: Выделить всё

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);
}
}

}
Я не ожидал, что RecyclerView в LocaleChoosingFragment вернется в первую позицию, когда наблюдатель в plannerFragment запускается наблюдателем в plannerFragment currentLocaleBeingViewed в Viewmodel. Все остальное работает как положено.

Подробнее здесь: https://stackoverflow.com/questions/782 ... ab-updated
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»