ネストされたSupport FragmentでonActivity Resultコールバックを受信できないソリューション

5888 ワード

事の原因はまずここをブラウズしてください.
主な回答:
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の中のいくつかの解決策は多かれ少なかれ問題があるので、自分で折衷案を選んで、1つのChildFragmentEventChild 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 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 CREATOR = new Parcelable.Creator() {
            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の起動を正しく処理できるかを明確にする必要があります.
転載は本文の住所を添付してください