@@@@@@@@@@@@@@@@@@@@@@@@@@@@
EDIT: Acabei não implementando esta solução porque havia outros problemas que isso tem. O Square lançou recentemente 2 bibliotecas que substituem fragmentos. Eu diria que essa pode ser uma alternativa melhor do que tentar hackear fragmentos para fazer algo que o Google não quer que eles façam.
http://corner.squareup.com/2014/01/mortar-and-flow.html
@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Achei que deveria apresentar essa solução para ajudar as pessoas que terão esse problema no futuro. Se você acompanhar a conversa do pôster original com outras pessoas e olhar o código que ele postou, verá que o pôster original eventualmente chega à conclusão de usar uma animação autônoma nos fragmentos filhos enquanto anima o fragmento pai. Esta solução não é ideal, pois força você a manter o controle de todos os fragmentos filhos, o que pode ser complicado ao usar um ViewPager com FragmentPagerAdapter.
Como eu uso fragmentos de criança em todos os lugares, criei essa solução que é eficiente e modular (para que possa ser facilmente removido) caso eles consigam consertar e essa animação autônoma não seja mais necessária.
Existem muitas maneiras de implementar isso. Escolhi usar um singleton e o chamo de ChildFragmentAnimationManager. Basicamente, ele acompanhará um fragmento filho para mim com base em seu pai e aplicará uma animação sem operação aos filhos quando solicitado.
public class ChildFragmentAnimationManager {
private static ChildFragmentAnimationManager instance = null;
private Map<Fragment, List<Fragment>> fragmentMap;
private ChildFragmentAnimationManager() {
fragmentMap = new HashMap<Fragment, List<Fragment>>();
}
public static ChildFragmentAnimationManager instance() {
if (instance == null) {
instance = new ChildFragmentAnimationManager();
}
return instance;
}
public FragmentTransaction animate(FragmentTransaction ft, Fragment parent) {
List<Fragment> children = getChildren(parent);
ft.setCustomAnimations(R.anim.no_anim, R.anim.no_anim, R.anim.no_anim, R.anim.no_anim);
for (Fragment child : children) {
ft.remove(child);
}
return ft;
}
public void putChild(Fragment parent, Fragment child) {
List<Fragment> children = getChildren(parent);
children.add(child);
}
public void removeChild(Fragment parent, Fragment child) {
List<Fragment> children = getChildren(parent);
children.remove(child);
}
private List<Fragment> getChildren(Fragment parent) {
List<Fragment> children;
if ( fragmentMap.containsKey(parent) ) {
children = fragmentMap.get(parent);
} else {
children = new ArrayList<Fragment>(3);
fragmentMap.put(parent, children);
}
return children;
}
}
Em seguida, você precisa ter uma classe que estende Fragment que todos os seus Fragments estendem (pelo menos seus Fragmentos Filhos). Eu já tive essa classe e a chamo de BaseFragment. Quando uma visualização de fragmentos é criada, nós a adicionamos ao ChildFragmentAnimationManager e a removemos quando é destruída. Você pode fazer isso em Attach / Detach ou em outros métodos de correspondência na sequência. Minha lógica para escolher Create / Destroy View foi porque se um Fragment não tem uma View, eu não me importo em animá-lo para continuar a ser visto. Essa abordagem também deve funcionar melhor com ViewPagers que usam Fragments, já que você não acompanhará cada Fragment que um FragmentPagerAdapter está mantendo, mas apenas 3.
public abstract class BaseFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Fragment parent = getParentFragment();
if (parent != null) {
ChildFragmentAnimationManager.instance().putChild(parent, this);
}
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onDestroyView() {
Fragment parent = getParentFragment();
if (parent != null) {
ChildFragmentAnimationManager.instance().removeChild(parent, this);
}
super.onDestroyView();
}
}
Agora que todos os seus fragmentos estão armazenados na memória pelo fragmento pai, você pode chamar animate neles assim, e seus fragmentos filhos não desaparecerão.
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ChildFragmentAnimationManager.instance().animate(ft, ReaderFragment.this)
.setCustomAnimations(R.anim.up_in, R.anim.up_out, R.anim.down_in, R.anim.down_out)
.replace(R.id.container, f)
.addToBackStack(null)
.commit();
Além disso, para que você tenha, aqui está o arquivo no_anim.xml que vai para sua pasta res / anim:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/linear_interpolator">
<translate android:fromXDelta="0" android:toXDelta="0"
android:duration="1000" />
</set>
Novamente, não acho que essa solução seja perfeita, mas é muito melhor do que para cada instância que você tem um fragmento filho, implementando código personalizado no fragmento pai para manter o controle de cada filho. Eu estive lá e não é divertido.
R.id.fragmentHolder
em relação a A, A1, A2, etc?