Como obter fragmentos existentes ao usar FragmentPagerAdapter

99

Tenho problemas para fazer meus fragmentos se comunicarem uns com os outros por meio do Activity, que está usando o FragmentPagerAdapter, como uma classe auxiliar que implementa o gerenciamento de guias e todos os detalhes de conexão ViewPagercom um associado TabHost. Implementei FragmentPagerAdapterda mesma forma que é fornecido pelo projeto de amostra do Android Support4Demos .

A principal questão é como posso obter um fragmento específico de FragmentManagerquando não tenho ID ou Tag? FragmentPagerAdapterestá criando os fragmentos e gerando automaticamente o Id e as tags.

Ismar Slomic
fonte
@ jk2K como isso pode ser uma duplicata de uma pergunta que foi feita 1 ano depois
Davi
@Dawit duplicado como um rótulo, não relacionado ao tempo, as perguntas posteriores têm visualizações mais altas
jk2K
A maioria das respostas aqui não funciona na produção, então verifique minha resposta em stackoverflow.com/a/54280113/2413303
EpicPandaForce

Respostas:

194

Resumo do problema

Nota: nesta resposta vou fazer referência FragmentPagerAdaptere seu código-fonte. Mas a solução geral também deve ser aplicada a FragmentStatePagerAdapter.

Se você está lendo isso, provavelmente já sabe que FragmentPagerAdapter/ FragmentStatePagerAdapterdeve ser criado Fragmentspara você ViewPager, mas após a recriação da atividade (seja a partir de uma rotação do dispositivo ou do sistema matando seu aplicativo para recuperar a memória),Fragments não serão criados novamente, mas sim seus instâncias recuperadas doFragmentManager . Agora diga que você Activityprecisa de uma referência para Fragmentstrabalhar com eles. Você não tem um idou tagpara estes criados Fragmentsporque os FragmentPagerAdapter define internamente . Então o problema é como obter uma referência a eles sem essa informação ...

Problema com as soluções atuais: depender de código interno

Muitas das soluções que eu vi sobre este e outras questões semelhantes confiar em obter uma referência ao existente Fragmentchamando FragmentManager.findFragmentByTag()e imitando o tag criado internamente:"android:switcher:" + viewId + ":" + id . O problema com isso é que você está contando com o código-fonte interno, que como todos sabemos não é garantido que permaneça o mesmo para sempre. Os engenheiros do Android no Google poderiam facilmente decidir mudar a tagestrutura que quebraria o seu código, deixando você incapaz de encontrar uma referência ao existente Fragments.

Solução alternativa sem depender de internos tag

Aqui está um exemplo simples de como obter uma referência ao Fragmentsretornado por FragmentPagerAdapterque não dependa do tagsconjunto interno do Fragments. A chave é substituir instantiateItem()e salvar as referências lá em vez de em getItem().

public class SomeActivity extends Activity {
    private FragmentA m1stFragment;
    private FragmentB m2ndFragment;

    // other code in your Activity...

    private class CustomPagerAdapter extends FragmentPagerAdapter {
        // other code in your custom FragmentPagerAdapter...

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

        @Override
        public Fragment getItem(int position) {
            // Do NOT try to save references to the Fragments in getItem(),
            // because getItem() is not always called. If the Fragment
            // was already created then it will be retrieved from the FragmentManger
            // and not here (i.e. getItem() won't be called again).
            switch (position) {
                case 0:
                    return new FragmentA();
                case 1:
                    return new FragmentB();
                default:
                    // This should never happen. Always account for each position above
                    return null;
            }
        }

        // Here we can finally safely save a reference to the created
        // Fragment, no matter where it came from (either getItem() or
        // FragmentManger). Simply save the returned Fragment from
        // super.instantiateItem() into an appropriate reference depending
        // on the ViewPager position.
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
            // save the appropriate reference depending on position
            switch (position) {
                case 0:
                    m1stFragment = (FragmentA) createdFragment;
                    break;
                case 1:
                    m2ndFragment = (FragmentB) createdFragment;
                    break;
            }
            return createdFragment;
        }
    }

    public void someMethod() {
        // do work on the referenced Fragments, but first check if they
        // even exist yet, otherwise you'll get an NPE.

        if (m1stFragment != null) {
            // m1stFragment.doWork();
        }

        if (m2ndFragment != null) {
            // m2ndFragment.doSomeWorkToo();
        }
    }
}

ou se você preferir trabalhar com em tagsvez de variáveis ​​/ referências de membros de classe, Fragmentsvocê também pode pegar o tagsconjunto FragmentPagerAdapterda mesma maneira: NOTA: isso não se aplica a, FragmentStatePagerAdapterpois não é definido tagsao criar seu Fragments.

@Override
public Object instantiateItem(ViewGroup container, int position) {
    Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
    // get the tags set by FragmentPagerAdapter
    switch (position) {
        case 0:
            String firstTag = createdFragment.getTag();
            break;
        case 1:
            String secondTag = createdFragment.getTag();
            break;
    }
    // ... save the tags somewhere so you can reference them later
    return createdFragment;
}

Observe que este método NÃO depende da imitação do tagconjunto interno FragmentPagerAdaptere, em vez disso, usa APIs adequadas para recuperá-los. Desta forma, mesmo que as tagalterações em versões futuras do, SupportLibraryvocê ainda esteja seguro.


Não esqueça que dependendo do design do seu Activity, o que Fragmentsvocê está tentando trabalhar pode ou não existir, então você deve levar isso em consideração fazendo nullverificações antes de usar suas referências.

Além disso, se em vez disso você estiver trabalhando com o FragmentStatePagerAdapter, então não deseja manter referências rígidas para o seu Fragmentsporque você pode ter muitas delas e referências rígidas as manteriam desnecessariamente na memória. Em vez disso, salve as Fragmentreferências em WeakReferencevariáveis em vez de nas padrão. Como isso:

WeakReference<Fragment> m1stFragment = new WeakReference<Fragment>(createdFragment);
// ...and access them like so
Fragment firstFragment = m1stFragment.get();
if (firstFragment != null) {
    // reference hasn't been cleared yet; do work...
}
Tony Chan
fonte
3
Esta é uma solução realmente boa, mas parece perder sua eficácia se você não souber quantos fragmentos serão transmitidos.
Riot Goes Woof
3
@Zorpix você pode armazenar os fragmentos criados em um HashMap: map.put (position, createdFragment);
Tom Bevelander
12
Isso merece a marca de seleção! Uma maneira muito inteligente e abrangente de fazer isso. Você me ajudou muito obrigado!
young_souvlaki
2
No início, essa solução parecia muito complicada, então eu a ignorei. Finalmente voltei ao assunto, porque as outras respostas não foram satisfatórias. E não foi tão difícil quanto pensei.
Suragch
1
não há necessidade de substituir nada e você realmente não deveria estar substituindo instantiateItem. a maneira correta de fazer isso é chamar instantiateItem no onCreatemétodo de sua atividade cercado por startUpdatee finishUpdate. Veja minha resposta para detalhes
morgwai
82

Eu encontrei a resposta para minha pergunta com base na seguinte postagem: reutilizando fragmentos em um fragmentpageradapter

Poucas coisas que aprendi:

  1. getItem(int position)no FragmentPagerAdapternome enganoso do que esse método realmente faz. Ele cria novos fragmentos, não retornando os existentes. Nesse sentido, o método deve ser renomeado para algo comocreateItem(int position) no Android SDK. Portanto, este método não nos ajuda a obter fragmentos.
  2. Com base na explicação na postagem de suporte FragmentPagerAdapterholds referência a fragmentos antigos, você deve deixar a criação dos fragmentos para o FragmentPagerAdaptere, portanto, o que significa que você não tem nenhuma referência aos fragmentos ou suas tags. Se você tiver uma tag de fragmento, pode facilmente recuperar a referência a ela FragmentManagerchamando findFragmentByTag(). Precisamos encontrar uma maneira de descobrir a tag de um fragmento em determinada posição da página.

Solução

Adicione o seguinte método auxiliar em sua classe para recuperar a tag do fragmento e enviá-la ao findFragmentByTag()método.

private String getFragmentTag(int viewPagerId, int fragmentPosition)
{
     return "android:switcher:" + viewPagerId + ":" + fragmentPosition;
}

NOTA! Este é um método idêntico FragmentPagerAdapterao usado ao criar novos fragmentos. Veja este link http://code.google.com/p/openintents/source/browse/trunk/compatibility/AndroidSupportV2/src/android/support/v2/app/FragmentPagerAdapter.java#104

Ismar Slomic
fonte
Aliás, há mais informações sobre o tópico neste Q&A: stackoverflow.com/questions/6976027/…
Thomas
1
qual é o parâmetro de entrada viewId? Qual vista?
Nilzor
@Nilzor viewId é o id do ViewPager.
Dr.jacky
Talvez, em vez de adivinhar a marca, o fragmento pudesse indicar sua marca para sua atividade em onAttach()?
bacia de
4
Este não é o caminho certo. A resposta de @Tony Chan é a melhor e correta.
Morteza Rastgoo
16

você não precisa substituir instantiateItemnem confiar na compatibilidade com o makeFragmentNamemétodo interno criando manualmente tags de fragmento.
instantiateItemé um método público , então você pode e realmente deve chamá-lo no onCreatemétodo de sua atividade rodeado de chamadas para startUpdatee finishUpdatemétodos descritos em PagerAdapter javadoc :

Uma chamada para o método startUpdate (ViewGroup) do PagerAdapter indica que o conteúdo do ViewPager está prestes a mudar. Uma ou mais chamadas para instantiateItem (ViewGroup, int) e / ou destroyItem (ViewGroup, int, Object) se seguirão e o fim de uma atualização será sinalizado por uma chamada para finishUpdate (ViewGroup).

Você pode então, pelo caminho acima, armazenar referências a instâncias de seus fragmentos em vars locais, se necessário. Consultar exemplo:

public class MyActivity extends AppCompatActivity {

    Fragment0 tab0; Fragment1 tab1;

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.myLayout);
        ViewPager viewPager = (ViewPager) findViewById(R.id.myViewPager);
        MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager());
        viewPager.setAdapter(adapter);
        ((TabLayout) findViewById(R.id.tabs)).setupWithViewPager(viewPager);

        adapter.startUpdate(viewPager);
        tab0 = (Fragment0) adapter.instantiateItem(viewPager, 0);
        tab1 = (Fragment1) adapter.instantiateItem(viewPager, 1);
        adapter.finishUpdate(viewPager);
    }

    class MyPagerAdapter extends FragmentPagerAdapter {

        public MyPagerAdapter(FragmentManager manager) {super(manager);}

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

        @Override public Fragment getItem(int position) {
            if (position == 0) return new Fragment0();
            if (position == 1) return new Fragment1();
            return null;  // or throw some exception
        }

        @Override public CharSequence getPageTitle(int position) {
            if (position == 0) return getString(R.string.tab0);
            if (position == 1) return getString(R.string.tab1);
            return null;  // or throw some exception
        }
    }
}

instantiateItemtentará primeiro obter referências a instâncias de fragmento existentes de FragmentManager. Somente se eles ainda não existirem, ele criará novos usando o getItemmétodo de seu adaptador e "armazenará" noFragmentManager para qualquer uso futuro.

É importante observar que, mesmo que você não precise obter referências para seus fragmentos, você ainda deve chamar instantiateItemtodas as suas guias circundadas por startUpdate/ finishUpdateem seu onCreatemétodo desta forma:

    adapter.startUpdate(viewPager);
    // ignoring return values of the below 2 calls, just side effects matter:
    adapter.instantiateItem(viewPager, 0);
    adapter.instantiateItem(viewPager, 1);
    adapter.finishUpdate(viewPager);

Se você não fizer isso, então você está arriscando que suas instâncias de fragmentos nunca será comprometida com FragmentManager: quando a sua atividade se torna plano instantiateItemserá chamado automaticamente para obter os seus fragmentos, mas startUpdate/ finishUpdate pode não (dependendo de detalhes de implementação) eo que eles basicamente fazer é começar / confirmar a FragmentTransaction.
Isso pode resultar em referências às instâncias de fragmento criadas sendo perdidas muito rapidamente (por exemplo, quando você gira sua tela) e recriadas com muito mais frequência do que o necessário. Dependendo de quão "pesados" seus fragmentos são, isso pode ter consequências de desempenho não desprezíveis.
Além disso, em tais casos, as instâncias de fragmentos armazenados em vars locais podemtornam-se obsoletos: se a plataforma Android tentar obtê-losFragmentManager por algum motivo, ele falhará e, portanto, criará e usará novos, enquanto seus vars ainda farão referência aos antigos.

Morgwai
fonte
1
Pode ser a melhor solução em alguns casos. Mas o que acontecerá se o FragmentManger matar o fragmento e recriá-lo?
woltran
1
@woltran FragmentManagernão pode simplesmente matar aleatoriamente ( destruir é a palavra certa aqui) seu Fragment(pense no que aconteceria se ele decidisse matar um Fragmentque está sendo exibido atualmente;)). Geralmente o ciclo de vida de a Fragmentestá vinculado ao seu Activity(consulte github.com/xxv/android-lifecycle para obter detalhes) -> a Fragmentsó pode ser destruído se tiver Activitysido destruído. Nesse caso, quando um usuário navegar de volta para o dado, Activityele onCreateserá chamado novamente e uma nova instância de Fragmentserá criada.
morgwai
Esta é a resposta REAL
MJ Studio
Você realmente deve criar fragmentos em vez de confiar que eles serão criados enquanto um usuário rola o ViewPager, por exemplo?
Ano de
@Yar sim, você realmente deveria. O trecho da documentação que forneci afirma isso claramente e a seção "Algumas informações adicionais" explica por quê.
morgwai
11

A forma como eu fiz isso é definir uma Hashtable de WeakReferences da seguinte maneira:

protected Hashtable<Integer, WeakReference<Fragment>> fragmentReferences;

Então, escrevi o método getItem () assim:

@Override
public Fragment getItem(int position) {

    Fragment fragment;
    switch(position) {
    case 0:
        fragment = new MyFirstFragmentClass();
        break;

    default:
        fragment = new MyOtherFragmentClass();
        break;
    }

    fragmentReferences.put(position, new WeakReference<Fragment>(fragment));

    return fragment;
}

Então você pode escrever um método:

public Fragment getFragment(int fragmentId) {
    WeakReference<Fragment> ref = fragmentReferences.get(fragmentId);
    return ref == null ? null : ref.get();
}

Isso parece funcionar bem e acho um pouco menos hacky do que o

"android:switcher:" + viewId + ":" + position

truque, pois não depende de como o FragmentPagerAdapter é implementado. Claro, se o fragmento foi liberado pelo FragmentPagerAdapter ou se ainda não foi criado, getFragment retornará null.

Se alguém encontrar algo errado com essa abordagem, comentários são mais que bem-vindos.

personne3000
fonte
int fragmentIddeve ser renomeado paraint position
lmaooooo
7
Eu estava usando uma abordagem muito semelhante. Mas isso falha quando o pager é criado a partir de um pacote savedState. por exemplo: a atividade vai para o segundo plano e volta para o primeiro plano depois que onSavedStateInstance () é chamado. Nesse caso, os métodos getItem () não serão chamados.
Anoop,
qual é a razão para criar seu próprio mapa, uma vez que já existe um no FragmentManager que está sempre atualizado? Veja minha resposta para detalhes.
morgwai
além disso, o fato de um fragmento ter sido destruído não garante que não haja referências fortes a ele (embora seja provável, mas NÃO garantido), caso em que seu mapa ainda conteria fragmentos obsoletos.
morgwai
1
Isso não funcionará corretamente depois que o sistema recriar os fragmentos.
EpicPandaForce
10

Eu criei este método que está funcionando para mim obter uma referência para o fragmento atual.

public static Fragment getCurrentFragment(ViewPager pager, FragmentPagerAdapter adapter) {
    try {
        Method m = adapter.getClass().getSuperclass().getDeclaredMethod("makeFragmentName", int.class, long.class);
        Field f = adapter.getClass().getSuperclass().getDeclaredField("mFragmentManager");
        f.setAccessible(true);
        FragmentManager fm = (FragmentManager) f.get(adapter);
        m.setAccessible(true);
        String tag = null;
        tag = (String) m.invoke(null, pager.getId(), (long) pager.getCurrentItem());
        return fm.findFragmentByTag(tag);
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } 
    return null;
}
Pepijn
fonte
Bom só lembrar de ter criado o Método e o Campo fora do método para melhor desempenho
Marcos Vasconcelos
2

a solução sugerida por @ personne3000 é boa, mas tem um problema: quando a atividade vai para o fundo e é interrompida pelo sistema (para obter um pouco de memória livre) e depois restaurada, o fragmentReferencesestará vazio, porquegetItem não estaria chamado.

A classe abaixo lida com essa situação:

public abstract class AbstractHolderFragmentPagerAdapter<F extends Fragment> extends FragmentPagerAdapter {

    public static final String FRAGMENT_SAVE_PREFIX = "holder";
    private final FragmentManager fragmentManager; // we need to store fragment manager ourselves, because parent's field is private and has no getters.

    public AbstractHolderFragmentPagerAdapter(FragmentManager fm) {
        super(fm);
        fragmentManager = fm;
    }

    private SparseArray<WeakReference<F>> holder = new SparseArray<WeakReference<F>>();

    protected void holdFragment(F fragment) {
        holdFragment(holder.size(), fragment);
    }

    protected void holdFragment(int position, F fragment) {
        if (fragment != null)
            holder.put(position, new WeakReference<F>(fragment));
    }

    public F getHoldedItem(int position) {
        WeakReference<F> ref = holder.get(position);
        return ref == null ? null : ref.get();
    }

    public int getHolderCount() {
        return holder.size();
    }

    @Override
    public void restoreState(Parcelable state, ClassLoader loader) { // code inspired by Google's FragmentStatePagerAdapter implementation
        super.restoreState(state, loader);
        Bundle bundle = (Bundle) state;
        for (String key : bundle.keySet()) {
            if (key.startsWith(FRAGMENT_SAVE_PREFIX)) {
                int index = Integer.parseInt(key.substring(FRAGMENT_SAVE_PREFIX.length()));
                Fragment f = fragmentManager.getFragment(bundle, key);
                holdFragment(index, (F) f);
            }
        }
    }

    @Override
    public Parcelable saveState() {
        Bundle state = (Bundle) super.saveState();
        if (state == null)
            state = new Bundle();

        for (int i = 0; i < holder.size(); i++) {
            int id = holder.keyAt(i);
            final F f = getHoldedItem(i);
            String key = FRAGMENT_SAVE_PREFIX + id;
            fragmentManager.putFragment(state, key, f);
        }
        return state;
    }
}
netimen
fonte
1

O principal obstáculo para obter uma alça para os fragmentos é que você não pode confiar em getItem (). Após uma mudança de orientação, as referências aos fragmentos serão nulas e getItem () não será chamado novamente.

Aqui está uma abordagem que não depende da implementação de FragmentPagerAdapter para obter a tag. Substitua instantiateItem () que retornará o fragmento criado a partir de getItem () ou encontrado no gerenciador de fragmentos.

@Override
public Object instantiateItem(ViewGroup container, int position) {
    Object value =  super.instantiateItem(container, position);

    if (position == 0) {
        someFragment = (SomeFragment) value;
    } else if (position == 1) {
        anotherFragment = (AnotherFragment) value;
    }

    return value;
}
Adão
fonte
0

Veja esta postagem sobre como retornar fragmentos do FragmentPagerAdapter. Depende de você saber o índice do seu fragmento - mas isso seria definido em getItem () (apenas na instanciação)

Comunidade
fonte
0

Consegui resolver esse problema usando ids em vez de tags. (Estou usando o FragmentStatePagerAdapter que usa meus fragmentos personalizados nos quais substituí o método onAttach, onde você salva o id em algum lugar:

@Override
public void onAttach(Context context){
    super.onAttach(context);
    MainActivity.fragId = getId();
}

E então você apenas acessa o fragmento facilmente dentro da atividade:

Fragment f = getSupportFragmentManager.findFragmentById(fragId);
user2740905
fonte
0

Não sei se esta é a melhor abordagem, mas nada mais funcionou para mim. Todas as outras opções, incluindo getActiveFragment, retornaram null ou fizeram o aplicativo travar.

Percebi que na rotação da tela o fragmento estava sendo anexado, então usei para enviar o fragmento de volta para a atividade.

No fragmento:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mListener = (OnListInteractionListener) activity;
        mListener.setListFrag(this);
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement OnFragmentInteractionListener");
    }
}

Então, na atividade:

@Override
public void setListFrag(MyListFragment lf) {
    if (mListFragment == null) {
        mListFragment = lf;
    }
}

E finalmente na atividade onCreate ():

if (savedInstanceState != null) {
    if (mListFragment != null)
        mListFragment.setListItems(items);
}

Essa abordagem anexa o fragmento visível real à atividade sem criar um novo.

TacoEater
fonte
0

Não tenho certeza se meu método era o correto ou a melhor maneira de fazer isso, já que sou relativamente iniciante em Java / Android, mas funcionou (tenho certeza de que viola os princípios de orientação a objetos, mas nenhuma outra solução funcionou para meu caso de uso).

Eu tinha uma atividade de hospedagem que estava usando um ViewPager com um FragmentStatePagerAdapter. Para obter referências aos fragmentos criados por FragmentStatePagerAdapter, criei uma interface de retorno de chamada dentro da classe de fragmento:

public interface Callbacks {
    public void addFragment (Fragment fragment);
    public void removeFragment (Fragment fragment);
}

Na atividade de hospedagem, implementei a interface e criei um LinkedHasSet para rastrear os fragmentos:

public class HostingActivity extends AppCompatActivity implements ViewPagerFragment.Callbacks {

    private LinkedHashSet<Fragment> mFragments = new LinkedHashSet<>();

    @Override
    public void addFragment (Fragment fragment) {
        mFragments.add(fragment);
    }

    @Override
    public void removeFragment (Fragment fragment) {
        mFragments.remove(fragment);
    }
}

Na classe ViewPagerFragment, adicionei os fragmentos à lista em onAttach e os removi em onDetach:

public class ViewPagerFragment extends Fragment {

    private Callbacks mCallbacks;

    public interface Callbacks {
        public void addFragment (Fragment fragment);
        public void removeFragment (Fragment fragment);
    } 

    @Override
    public void onAttach (Context context) {
        super.onAttach(context);
        mCallbacks = (Callbacks) context;
        // Add this fragment to the HashSet in the hosting activity
        mCallbacks.addFragment(this);
    }

    @Override
    public void onDetach() {
        super.onDetach();
        // Remove this fragment from the HashSet in the hosting activity
        mCallbacks.removeFragment(this);
        mCallbacks = null;
    }
}

Dentro da atividade de hospedagem, você agora poderá usar mFragments para iterar através dos fragmentos que existem atualmente no FragmentStatePagerAdapter.

Sbearben
fonte
0

Esta classe faz o truque sem depender de tags internas. Aviso: os fragmentos devem ser acessados ​​usando o método getFragment e não getItem.

public class ViewPagerAdapter extends FragmentPagerAdapter {

    private final Map<Integer, Reference<Fragment>> fragments = new HashMap<>();
    private final List<Callable0<Fragment>> initializers = new ArrayList<>();
    private final List<String> titles = new ArrayList<>();

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

    void addFragment(Callable0<Fragment> initializer, String title) {
        initializers.add(initializer);
        titles.add(title);
    }

    public Optional<Fragment> getFragment(int position) {
        return Optional.ofNullable(fragments.get(position).get());
    }

    @Override
    public Fragment getItem(int position) {
        Fragment fragment =  initializers.get(position).execute();
        return fragment;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Fragment fragment = (Fragment) super.instantiateItem(container, position);
        fragments.put(position, new WeakReference<>(fragment));
        return fragment;
    }

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

    @Override
    public CharSequence getPageTitle(int position) {
        return titles.get(position);
    }
}
Alex Miragall
fonte
-5

Basta tentar este código,

public class MYFragmentPAdp extends FragmentPagerAdapter {

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

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

     @Override
     public Fragment getItem(int position) {
         if (position == 0)
             Fragment fragment = new Fragment1();
         else (position == 1)
             Fragment fragment = new Fragment2();
         return fragment;
     }
}
Najib Ahmed Puthawala
fonte
Najib, como expliquei na minha resposta abaixo getItem () está criando um novo fragmento em vez de retornar os existentes, como seria de esperar, dado o nome get e não create . Veja minha solução no mesmo post.
Ismar Slomic
Fragment fragment = new YourCustomFragmentClass (); escreva aqui verifique isso.
Najib Ahmed Puthawala
Ainda não entendo como isso muda o fato de que você está criando um novo fragmento em vez de obter um existente ..
Ismar Slomic
Você ainda inicializa e retorna para seu fragmento personalizado, como Fragment fragment = new YourFragment (); fragmento de retorno;
Najib Ahmed Puthawala