@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
编辑:我最终没有实现这个解决方案,因为它还有其他问题。Square 最近推出了 2 个替换片段的库。我想说这实际上可能是一个比试图破解片段做谷歌不希望他们做的事情更好的选择。
http://corner.squareup.com/2014/01/mortar-and-flow.html
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
我想我会提出这个解决方案来帮助将来遇到这个问题的人。如果您追溯原始发布者与其他人的对话,并查看他发布的代码,您会看到原始发布者最终得出在子片段上使用无操作动画同时为父片段设置动画的结论。此解决方案并不理想,因为它会强制您跟踪所有子片段,这在将 ViewPager 与 FragmentPagerAdapter 一起使用时可能会很麻烦。
由于我在所有地方都使用子片段,因此我想出了这个高效且模块化的解决方案(因此可以轻松删除),以防他们修复它并且不再需要这种无操作动画。
有很多方法可以实现这一点。我选择使用单例,我称之为 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;
}
}
接下来,您需要有一个扩展所有 Fragment 扩展的 Fragment 的类(至少是您的子 Fragment)。我已经有这门课了,我称之为 BaseFragment。创建片段视图时,我们将其添加到 ChildFragmentAnimationManager,并在其销毁时将其删除。您可以在附加/分离或序列中的其他匹配方法上执行此操作。我选择 Create/Destroy View 的逻辑是因为如果 Fragment 没有 View,我不关心动画它以继续被看到。这种方法也应该更适用于使用 Fragment 的 ViewPager,因为您不会跟踪 FragmentPagerAdapter 持有的每一个 Fragment,而只会跟踪 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();
}
}
现在你所有的 Fragment 都由父 Fragment 存储在内存中,你可以像这样对它们调用 animate ,你的子 Fragment 不会消失。
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>
同样,我不认为这个解决方案是完美的,但它比每个实例都有一个子片段要好得多,在父片段中实现自定义代码以跟踪每个子片段。我去过那里,它并不好玩。