美文网首页Android知识
嵌套Support Fragment无法接收onActivity

嵌套Support Fragment无法接收onActivity

作者: SoloHo | 来源:发表于2014-12-11 16:03 被阅读878次

    事情的原因先浏览下这里.

    其中主要回复:

    Sorry, the support library can't do the same thing as the platform, because it has to run on older versions of the platform that don't support fragments, only having the integer request code. Over time, moving to the platform implementation of fragments is the solution to this.

    如果界面的设计如下:

    Activity/
            Fragment/
                    Fragment
    

    因为兼容包的问题,我们无法接收到onActivityResult方法的回调,并且StackOverFlow里面的一些解决方法因为或多或少都有点问题,所以自己选了个折中的方案,制作了一个ChildFragmentEvent帮助Child Fragment来利用Parent Fragment来启动

    Create ChildFragmentEvent

    package im.youji.app.utils;
    
    import android.content.Intent;
    import android.os.Bundle;
    import android.os.Parcel;
    import android.os.Parcelable;
    import android.support.v4.app.Fragment;
    import android.util.SparseArray;
    
    /**
     * Created by solo on 14/10/1.
     */
    public class ChildFragmentEvent {
    
        private final Fragment parentFragment;
        private SparseArray<ChildFragmentItem> childFragments;
    
        public static interface IStartActivityBehavior {
            void startActivityForResult(Intent intent, int requestCode, Fragment fragment);
        }
    
        public ChildFragmentEvent(Fragment parentFragment, Bundle savedInstanceState) {
            this.parentFragment = parentFragment;
            if (savedInstanceState != null) {
                childFragments = savedInstanceState.getSparseParcelableArray("childFragments");
            } else {
                childFragments = new SparseArray<>();
            }
        }
    
        public void onSaveInstanceState(Bundle outState) {
            outState.putSparseParcelableArray("childFragments", childFragments);
        }
    
        public int register(int requestCode, Fragment fragment) {
            int parentRequestCode = childFragments.size() + 1;
            childFragments.put(parentRequestCode, new ChildFragmentItem(requestCode, fragment.getId(), fragment.getTag()));
            return parentRequestCode;
        }
    
        public void dispatch(int parentRequestCode, int resultCode, Intent data) {
            ChildFragmentItem item = childFragments.get(parentRequestCode);
            if (item == null) {
                return;
            }
            Fragment fragment = null;
            if (item.getId() != null) {
                fragment = parentFragment.getChildFragmentManager().findFragmentById(item.getId());
            } else if (item.getTag() != null) {
                fragment = parentFragment.getChildFragmentManager().findFragmentByTag(item.getTag());
            }
            if (fragment != null) {
                fragment.onActivityResult(item.getRequestCode(), resultCode, data);
            }
        }
    
        private static class ChildFragmentItem implements Parcelable {
            int requestCode;
            Integer id;
            String tag;
    
            public ChildFragmentItem(int requestCode, int id, String tag) {
                this.requestCode = requestCode;
                this.id = id;
                this.tag = tag;
            }
    
            public int getRequestCode() {
                return requestCode;
            }
    
            public Integer getId() {
                return id;
            }
    
            public String getTag() {
                return tag;
            }
    
            @Override
            public int describeContents() {
                return 0;
            }
    
            @Override
            public void writeToParcel(Parcel dest, int flags) {
                dest.writeInt(this.requestCode);
                dest.writeValue(this.id);
                dest.writeString(this.tag);
            }
    
            private ChildFragmentItem(Parcel in) {
                this.requestCode = in.readInt();
                this.id = (Integer) in.readValue(Integer.class.getClassLoader());
                this.tag = in.readString();
            }
    
            public static final Parcelable.Creator<ChildFragmentItem> CREATOR = new Parcelable.Creator<ChildFragmentItem>() {
                public ChildFragmentItem createFromParcel(Parcel source) {
                    return new ChildFragmentItem(source);
                }
    
                public ChildFragmentItem[] newArray(int size) {
                    return new ChildFragmentItem[size];
                }
            };
        }
    
    }
    

    How to use

    Parent Fragment

    import android.support.v4.app.Fragment;
    
    public class EventGroupFragment extends Fragment implements ChildFragmentEvent.IStartActivityBehavior {
        private ChildFragmentEvent childFragmentEvent;
        
        @Override
        public void onCreate(Bundle savedInstanceState) {
            childFragmentEvent = new ChildFragmentEvent(this, savedInstanceState);
        }
        @Override
        public void onSaveInstanceState(Bundle outState) {
           childFragmentEvent.onSaveInstanceState(outState);
        }
        @Override
        public void startActivityForResult(Intent intent, int requestCode, Fragment fragment) {
            // get the parent requestCode after register
            super.startActivityForResult(intent, childFragmentEvent.register(requestCode, fragment));
        }
        @Override
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
            // dispatch to child fragments
            childFragmentEvent.dispatch(requestCode, resultCode, data);
        }
    }
    

    Child Fragment

    // Use this code to startActivity
    ((ChildFragmentEvent.IStartActivityBehavior) getParentFragment())
                    .startActivityForResult(intent, REQUEST_SIMPLE, this);
                    
    // Get Result
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQUEST_SIMPLE:
                // do something
                break;
        }
    }
    

    End

    最后,如果项目设计过于复杂,使用上面这种折中方法也会导致混乱,比如嵌套Fragment过多,需要明确知道哪个ParentFragment能够正确处理启动StartActivity。

    转载请附上本文地址

    相关文章

      网友评论

        本文标题:嵌套Support Fragment无法接收onActivity

        本文链接:https://www.haomeiwen.com/subject/rkbntttx.html