@@@@@@@@@@@@@@@@@@@@@@@@@@@
EDIT: Am Ende habe ich diese Lösung nicht implementiert, da es andere Probleme gab, die dies hat. Square hat kürzlich zwei Bibliotheken herausgebracht, die Fragmente ersetzen. Ich würde sagen, dies könnte tatsächlich eine bessere Alternative sein, als zu versuchen, Fragmente in etwas zu hacken, das Google nicht will.
http://corner.squareup.com/2014/01/mortar-and-flow.html
@@@@@@@@@@@@@@@@@@@@@@@@@@@
Ich dachte, ich würde diese Lösung aufstellen, um Menschen zu helfen, die dieses Problem in Zukunft haben. Wenn Sie die Konversation der Originalposter mit anderen Personen nachverfolgen und sich den von ihm geposteten Code ansehen, werden Sie feststellen, dass das Originalposter schließlich zu dem Schluss kommt, dass beim Animieren des übergeordneten Fragments eine No-Op-Animation für die untergeordneten Fragmente verwendet wird. Diese Lösung ist nicht ideal, da Sie gezwungen sind, alle untergeordneten Fragmente im Auge zu behalten. Dies kann bei Verwendung eines ViewPagers mit FragmentPagerAdapter umständlich sein.
Da ich überall Kinderfragmente verwende, habe ich diese Lösung entwickelt, die effizient und modular ist (so dass sie leicht entfernt werden kann), falls sie jemals repariert wird und diese No-Op-Animation nicht mehr benötigt wird.
Es gibt viele Möglichkeiten, wie Sie dies implementieren können. Ich habe mich für einen Singleton entschieden und nenne ihn ChildFragmentAnimationManager. Grundsätzlich wird ein untergeordnetes Fragment für mich anhand seines übergeordneten Elements verfolgt und auf Anfrage eine No-Op-Animation auf die Kinder angewendet.
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;
}
}
Als nächstes benötigen Sie eine Klasse, die Fragment erweitert, die alle Ihre Fragmente erweitern (zumindest Ihre untergeordneten Fragmente). Ich hatte diese Klasse bereits und nenne sie BaseFragment. Wenn eine Fragmentansicht erstellt wird, fügen wir sie dem ChildFragmentAnimationManager hinzu und entfernen sie, wenn sie zerstört wird. Sie können dies mit Attach / Detach oder anderen Übereinstimmungsmethoden in der Sequenz tun. Meine Logik für die Auswahl "Ansicht erstellen / zerstören" war, dass es mir egal ist, ein Fragment zu animieren, damit es weiterhin angezeigt wird, wenn es keine Ansicht hat. Dieser Ansatz sollte auch mit ViewPagern besser funktionieren, die Fragmente verwenden, da Sie nicht jedes einzelne Fragment verfolgen, das ein FragmentPagerAdapter enthält, sondern nur 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();
}
}
Nachdem alle Ihre Fragmente vom übergeordneten Fragment gespeichert wurden, können Sie sie wie folgt animieren, und Ihre untergeordneten Fragmente verschwinden nicht mehr.
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();
Nur damit Sie es haben, finden Sie hier die Datei no_anim.xml, die sich in Ihrem Ordner res / anim befindet:
<?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>
Auch hier denke ich nicht, dass diese Lösung perfekt ist, aber sie ist viel besser als für jede Instanz, in der Sie ein untergeordnetes Fragment haben, und implementiert benutzerdefinierten Code im übergeordneten Fragment, um die Übersicht über jedes untergeordnete Fragment zu behalten. Ich war dort und es macht keinen Spaß.
R.id.fragmentHolder
in Bezug auf A, A1, A2 usw.?