@@@@@@@@@@@@@@@@@@@@@@@@@@
編集:これには他の問題があったため、このソリューションを実装しないことになりました。Square は最近、フラグメントを置き換える 2 つのライブラリを発表しました。これは、フラグメントをハッキングして、Googleが望んでいないことを実行しようとするよりも、実際にはより良い代替手段であると言えます。
http://corner.squareup.com/2014/01/mortar-and-flow.html
@@@@@@@@@@@@@@@@@@@@@@@@@@
将来この問題を抱えている人々を助けるために、この解決策を提示したいと思いました. 元の投稿者の他の人との会話をたどって、彼が投稿したコードを見ると、元の投稿者が最終的に、親フラグメントをアニメーション化しながら、子フラグメントにノーオペレーション アニメーションを使用するという結論に達することがわかります。このソリューションは、FragmentPagerAdapter で ViewPager を使用するときに面倒なすべての子フラグメントを追跡する必要があるため、理想的ではありません。
私はあらゆる場所で子フラグメントを使用しているので、効率的でモジュラーな (簡単に削除できる) このソリューションを思いつきました。
これを実装する方法はたくさんあります。シングルトンを使用することにしました。これを ChildFragmentAnimationManager と呼びます。基本的に、親に基づいて子フラグメントを追跡し、要求されたときに何もしないアニメーションを子に適用します。
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;
}
}
次に、すべてのフラグメントが拡張するフラグメントを拡張するクラスが必要です (少なくとも子フラグメント)。私はすでにこのクラスを持っていて、それを BaseFragment と呼んでいます。フラグメント ビューが作成されると、それを ChildFragmentAnimationManager に追加し、破棄されると削除します。これを onAttach/Detach で行うか、シーケンス内の他の一致する方法で行うことができます。Create/Destroy View を選択した私のロジックは、Fragment に View がない場合、引き続き表示されるようにアニメーション化することを気にしないためです。このアプローチは、FragmentPagerAdapter が保持しているすべての Fragment を追跡するのではなく、3 つだけを追跡するため、Fragments を使用する ViewPagers でより適切に機能するはずです。
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();
}
}
すべてのフラグメントが親フラグメントによってメモリに保存されたので、このようにアニメーションを呼び出すことができ、子フラグメントは消えません。
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();
また、参考までに、 res/anim フォルダーにある no_anim.xml ファイルを次に示します。
<?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>
繰り返しますが、このソリューションが完璧だとは思いませんが、子フラグメントを持つすべてのインスタンスに対して、親フラグメントにカスタム コードを実装して各子を追跡するよりもはるかに優れています。私はそこに行ったことがありますが、面白くありません。