@@@@@@@@@@@@@@@@@@@@@@@@@@@@
CHỈNH SỬA: Tôi đã kết thúc giải pháp này vì có những vấn đề khác mà điều này có. Square gần đây đã ra mắt với 2 thư viện thay thế các mảnh. Tôi muốn nói rằng đây thực sự có thể là một giải pháp thay thế tốt hơn việc cố gắng hack các mảnh để làm điều gì đó mà google không muốn họ làm.
http://corner.squareup.com/2014/01/mortar-and-flow.html
@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Tôi nghĩ rằng tôi sẽ đưa ra giải pháp này để giúp những người gặp vấn đề này trong tương lai. Nếu bạn theo dõi cuộc trò chuyện trên áp phích gốc với những người khác và nhìn vào đoạn mã anh ấy đã đăng, bạn sẽ thấy người đăng gốc cuối cùng đi đến kết luận sử dụng hoạt ảnh không chọn trên các phân đoạn con trong khi tạo hoạt ảnh cho phân đoạn chính. Giải pháp này không lý tưởng vì nó buộc bạn phải theo dõi tất cả các đoạn con, điều này có thể phức tạp khi sử dụng ViewPager với FragmentPagerAdapter.
Vì tôi sử dụng Child Fragment khắp nơi nên tôi đã nghĩ ra giải pháp này hiệu quả và có tính mô-đun (vì vậy nó có thể dễ dàng loại bỏ) trong trường hợp họ sửa nó và hoạt ảnh no-op này không còn cần thiết nữa.
Có rất nhiều cách bạn có thể thực hiện điều này. Tôi đã chọn sử dụng một singleton và tôi gọi nó là ChildFragmentAnimationManager. Về cơ bản, nó sẽ theo dõi một đoạn con cho tôi dựa trên đoạn cha mẹ của nó và sẽ áp dụng hoạt ảnh no-op cho đứa trẻ khi được hỏi.
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;
}
}
Tiếp theo, bạn cần có một lớp mở rộng Fragment mà tất cả các Fragment của bạn đều mở rộng (ít nhất là các Fragment con của bạn). Tôi đã có lớp này và tôi gọi nó là BaseFragment. Khi chế độ xem phân mảnh được tạo, chúng tôi thêm nó vào ChildFragmentAnimationManager và xóa nó khi nó bị phá hủy. Bạn có thể làm điều này onAttach / Detach, hoặc các phương pháp so khớp khác trong trình tự. Logic của tôi khi chọn Create / Destroy View là vì nếu Fragment không có View, tôi không quan tâm đến việc tạo hoạt ảnh để tiếp tục được nhìn thấy. Cách tiếp cận này cũng sẽ hoạt động tốt hơn với các ViewPager sử dụng Fragment vì bạn sẽ không theo dõi từng Fragment đơn lẻ mà FragmentPagerAdapter đang nắm giữ mà chỉ có 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();
}
}
Giờ đây, tất cả các Phân đoạn của bạn được lưu trữ trong bộ nhớ bởi phân đoạn mẹ, bạn có thể gọi hoạt ảnh trên chúng như thế này và các phân đoạn con của bạn sẽ không biến mất.
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();
Ngoài ra, bạn có nó, đây là tệp no_anim.xml nằm trong thư mục res / anim của bạn:
<?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>
Một lần nữa, tôi không nghĩ giải pháp này là hoàn hảo, nhưng nó tốt hơn nhiều so với mọi trường hợp bạn có Phân đoạn con, triển khai mã tùy chỉnh trong phân đoạn mẹ để theo dõi từng phân đoạn con. Tôi đã ở đó, và không có gì vui.
R.id.fragmentHolder
đối với A, A1, A2, vv với?