FragmentPagerAdapter странное поведение

Итак, у меня следующая проблема с FragmentPagerAdapter. У меня есть TabLayout с 3 вкладками, представляющими 3 фрагмента, которые я могу переключать. Поэтому, когда я переключаюсь на третий фрагмент, по какой-то причине исчезает первый (или его вид). Кто-нибудь знает, как исправить эту проблему? Заранее спасибо.

public class SectionsPagerAdapter extends FragmentPagerAdapter {

private static final int FRAGMENT_COUNT = 3;

private final List<Fragment> listOfFragments = new ArrayList<>();

public SectionsPagerAdapter(FragmentManager fm) {
    super(fm);
}

@Override
public Fragment getItem(int position) {
    return listOfFragments.get(position);
}

@Override
public int getCount() {
    return FRAGMENT_COUNT;
}

public void addFragment(Fragment fragment) {
    listOfFragments.add(fragment);
}


}

Это код для FragmentPagerAdapter.

не могли бы вы показать код, куда вы привязываете свой адаптер?

Rutvik Bhatt 07.06.2018 12:17

И я думаю, что исправил это :) Единственное, что я сделал, это переопределил метод destroyItem () FragmentPagerAdapter с пустым телом (без super).

RadoVidjen 07.06.2018 12:19
1
2
2 960
4

Ответы 4

Я не знаю, в чем твоя проблема. но если в вашем приложении всего 3 фрагмента, вы можете попробовать метод setOffscreenPageLimit из ViewPager

ViewPager.setOffscreenPageLimit(3);

Спасибо за комментарий! Проблема в том, что по какой-то причине, если у вас есть три фрагмента, и, скажем, вы устанавливаетеCurrentItem (1) (что означает, что второй фрагмент используется по умолчанию), затем переходите к последнему фрагменту (третьему), а затем вернитесь к первому фрагменту, есть нет первого фрагмента, похоже, что он по какой-то причине удален (или, по крайней мере, его макет). Как я уже упоминал в своем комментарии, я исправил это, переопределив destroyItem () из FragmentPagerAdapter.

RadoVidjen 07.06.2018 12:23

хорошо отлично. и опубликуйте свое решение в качестве ответа, чтобы, если кто-либо другой посетит этот вопрос, ваш ответ поможет им решить его проблему.

Bhavesh Rangani 07.06.2018 12:29

Я действительно не знаю, что случилось, но это мой код, надеюсь, это поможет вам

public class AdapterFragmentViewPager extends FragmentPagerAdapter {

    private List<Fragment> fragmentList = new ArrayList<>();


    public AdapterFragmentViewPager(FragmentManager fm) {
        super(fm);
    }

    public void addFragment(Fragment fragment) {
        fragmentList.add(fragment);
    }

    @Override
    public Fragment getItem(int position) {
        return fragmentList.get(position);
    }

    @Override
    public int getCount() {
        return fragmentList.size();
    }
}

а это мой Tablayout:

private AdapterFragmentViewPager adapterFragmentViewPager = new AdapterFragmentViewPager(getSupportFragmentManager());
TabLayout.Tab home = tabLayout.newTab();
        tabLayout.addTab(home);

        TabLayout.Tab newest = tabLayout.newTab();
        tabLayout.addTab(newest);

        TabLayout.Tab author = tabLayout.newTab();
        tabLayout.addTab(author);

        TabLayout.Tab category = tabLayout.newTab();
        tabLayout.addTab(category);

        TabLayout.Tab saved = tabLayout.newTab();
        tabLayout.addTab(saved);


        adapterFragmentViewPager.addFragment(FragmentHome.newInstance());
        adapterFragmentViewPager.addFragment(FragmentQuote.newInstance());
        adapterFragmentViewPager.addFragment(FragmentAuthor.newInstance());
        adapterFragmentViewPager.addFragment(FragmentCategory.newInstance());
        adapterFragmentViewPager.addFragment(FragmentFavorites.newInstance());
        viewPager.setAdapter(adapterFragmentViewPager);
        tabLayout.setupWithViewPager(viewPager);

Одна из проблем здесь - немного сбивающий с толку API.

В FragmentPagerAdaptergetItem(int position) фактически означает «создать элемент». Другими словами, вам не следует пытаться вручную кэшировать фрагменты внутри списка в вашем адаптере.

@Override
public Fragment getItem(int position) {
    return listOfFragments.get(position); //No! don't do this
}

Несмотря на то, что это может показаться нелогичным, на самом деле вам следует создать новый экземпляр фрагмента, который вы хотите, внутри getItem, очень точно придерживаясь официального примера Google:

@Override 
public Fragment getItem(int position) {
    switch (position) {
        case 0: 
            return FirstFragment.getInstance();
        case 1:
            return SecondFragment.getInstance(); 
    }
}

В противном случае вы столкнетесь с проблемами, когда кеш FragmentManager и ваш собственный кеш List<Fragment> не синхронизированы. Короче говоря, кеширование фрагментов выполняется FragmentManager, и вам не нужно настраивать собственное кэширование.

И я думаю, что исправил это :) Единственное, что я сделал, это переопределил метод destroyItem () FragmentPagerAdapter с пустым телом (без super).

На самом деле, если это так, тогда вы должны были передать childFragmentManager в FragmentPagerAdapter

EpicPandaForce 11.09.2020 20:24

Другие вопросы по теме