NotifyDataSetChanged не работает в FragmentStateAdapter с Viewpager2 - PullRequest
0 голосов
/ 13 июля 2020

Я делаю страницу выбора файла с помощью viewpager2 с FragmentStateAdapter. На одной из страниц я показываю все подключенные устройства хранения, на которых я хотел бы коснуться, чтобы просмотреть содержимое, но я хочу, чтобы содержимое находилось на другом фрагменте.

Я хочу заменить фрагмент другим в последнем страница просмотра. но со следующим кодом страница просто обновляется и новый фрагмент не создается, поскольку createFragment не вызывается.

My PagerAdapter

public static class PagerAdapter extends FragmentStateAdapter {


        private Fragment mFragmentAtPos0;
        private final FragmentManager mFragmentManager;
        private final FirstPageListener listener = new FirstPageListener();
        public final class FirstPageListener implements
                FirstPageFragmentListener {
            public void onSwitchToNextFragment() {
                mFragmentManager.beginTransaction().remove(mFragmentAtPos0)
                        .commit();
                if (mFragmentAtPos0 instanceof FilesandFolder_Others_MainPage){
                    mFragmentAtPos0 = new FileExplorer(listener);
                }else{ // Instance of NextFragment
                    mFragmentAtPos0 = new FilesandFolder_Others_MainPage(listener);
                }
                notifyDataSetChanged();
            }
            public void onSwitchToNextFragment(Bundle bundle) {
//                mFragmentManager.beginTransaction().remove(mFragmentAtPos0)
//                        .commit();
                if (mFragmentAtPos0 instanceof FilesandFolder_Others_MainPage){
                    mFragmentAtPos0 = new FileExplorer(listener);
                    mFragmentAtPos0.setArguments(bundle);
                }else{ // Instance of NextFragment
                    mFragmentAtPos0 = new FilesandFolder_Others_MainPage(listener);
                    mFragmentAtPos0.setArguments(bundle);
                }
                notifyDataSetChanged();
//                notifyItemChanged(getItemPosition(mFragmentAtPos0));
            }
        }


//        @Override
//        public void onBindViewHolder(@NonNull FragmentViewHolder holder, int position, @NonNull List<Object> payloads) {
//            super.onBindViewHolder(holder, position, payloads);
//            if (position == getItemPosition(mFragmentAtPos0)) {
//
//                Fragment f = mFragmentManager.findFragmentByTag("f" + holder.getItemId());
//                if (f != null) {
//                    mFragmentManager.beginTransaction().replace(holder.getItemId(), )
//                }
//            }
//        }

        private int getItemPosition(Fragment mFragmentAtPos0) {
            for (int i = 0; i < getItemCount(); i++){

                if (createFragment(i).equals(mFragmentAtPos0)){
                    return i;
                }
            }
            return -1;
        }


        public PagerAdapter(FragmentActivity fm) {
            super(fm);
            mFragmentManager = fm.getSupportFragmentManager();
            mFragmentAtPos0 = new FilesandFolder_Others_MainPage(listener);
        }

        @NonNull
        @Override
        public Fragment createFragment(int position) {
            switch (position){
                case 0:
                    return new AppSelectionFragment();
                case 1:
                    return new Photos();
                case 2:
                    return new VideoGalleryFragment();
                case 3:
                    return new Gallery();
                default:
                    return mFragmentAtPos0;
            }
        }

        @Override
        public int getItemCount() {
            return 5;
        }
    }

Вот конструктор фрагмента, из которого Я хотел бы заменить на другой фрагмент:

    private static FileSelection.PagerAdapter.FirstPageListener pageFragmentListener;

    public FilesandFolder_Others_MainPage() {
    }
    public FilesandFolder_Others_MainPage(FileSelection.PagerAdapter.FirstPageListener firstPageFragmentListener) {
        pageFragmentListener = firstPageFragmentListener;
    }

И при нажатии на представление должен вызываться следующий код: -

Bundle bundle = new Bundle();
bundle.putString("PATH", volumes.get(position).path);
pageFragmentListener.onSwitchToNextFragment(bundle);

Я просмотрел все через stackoverflow , и никогда не видел правильного ответа с viewpager 2 и FragmentStateAdapter, поскольку все, кажется, используют Viewpager

Я пытался реализовать это: - FragmentStateAdapter для ViewPager2 notifyItemChanged не работает должным образом

, но не понимал, как редактировать мой код. Пожалуйста, помогите, заранее спасибо

1 Ответ

0 голосов
/ 26 августа 2020

Была такая же проблема, и вот что я обнаружил:

FragmentStateAdapter имеет метод onBindViewHolder(holder, position, payloads), который вы можете переопределить (в отличие от onBindViewHolder(holder, position), который является окончательным). Этот метод вызывается, когда вы вызываете методы notify, а для методов notifyItemChanged(), notifyItemRangeChanged() вы можете получить доступ к фрагменту и обновить его вручную.

Вот код для доступа к фрагменту:

public void onBindViewHolder(@NonNull FragmentViewHolder holder, int position, @NonNull List<Object> payloads) {

    String tag = "f" + holder.getItemId();

    Fragment fragment = fragmentManager.findFragmentByTag(tag);

    if (fragment != null) {
        //manual update fragment
    } else {
        // fragment might be null, if it`s call of notifyDatasetChanged() 
        // which is updates whole list, not specific fragment
        super.onBindViewHolder(holder, position, payloads);
    }
}

FragmentStateAdapter помечены его фрагментами как "f" + holder.getItemId(), поэтому это работает.

Также вы можете использовать DiffUtil, и это лучший способ. Вот хороший пример решения этой проблемы и несколько ссылок в конце для лучшего понимания ViewPager2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...