I have been using the new nested fragment API that Android includes in the support library.

The problem that I am facing with nested fragments is that, if a nested fragment (that is, a fragment that has been added to another fragment via the FragmentManagerreturned by getChildFragmentManager()) calls startActivityForResult(), the nested fragment's onActivityResult() method is not called. However, both the parent fragment's onActivityResult() and activity's onActivityResult() do get called.

我不知道我是否遗漏了嵌套片段的某些内容,但我没有预料到所描述的行为.下面是重现此问题的代码.如果有人能为我指明正确的方向,并向我解释我做错了什么,我将不胜感激:

package com.example.nestedfragmentactivityresult;

import android.media.RingtoneManager;
import android.os.Bundle;
import android.content.Intent;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends FragmentActivity
{
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        this.getSupportFragmentManager()
            .beginTransaction()
            .add(android.R.id.content, new ContainerFragment())
            .commit();
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);

        // This is called
        Toast.makeText(getApplication(),
            "Consumed by activity",
            Toast.LENGTH_SHORT).show();
    }

    public static class ContainerFragment extends Fragment
    {
        public final View onCreateView(LayoutInflater inflater,
                                       ViewGroup container,
                                       Bundle savedInstanceState)
        {
            View result = inflater.inflate(R.layout.test_nested_fragment_container,
                container,
                false);

            return result;
        }

        public void onActivityCreated(Bundle savedInstanceState)
        {
            super.onActivityCreated(savedInstanceState);
            getChildFragmentManager().beginTransaction()
                .add(R.id.content, new NestedFragment())
                .commit();
        }

        public void onActivityResult(int requestCode,
                                     int resultCode,
                                     Intent data)
        {
            super.onActivityResult(requestCode, resultCode, data);

            // This is called
            Toast.makeText(getActivity(),
                "Consumed by parent fragment",
                Toast.LENGTH_SHORT).show();
        }
    }

    public static class NestedFragment extends Fragment
    {
        public final View onCreateView(LayoutInflater inflater,
                                       ViewGroup container,
                                       Bundle savedInstanceState)
        {
            Button button = new Button(getActivity());
            button.setText("Click me!");
            button.setOnClickListener(new View.OnClickListener()
            {
                public void onClick(View v)
                {
                    Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
                    startActivityForResult(intent, 0);
                }
            });

            return button;
        }

        public void onActivityResult(int requestCode,
                                     int resultCode,
                                     Intent data)
        {
            super.onActivityResult(requestCode, resultCode, data);

            // This is NOT called
            Toast.makeText(getActivity(),
                "Consumed by nested fragment",
                Toast.LENGTH_SHORT).show();
        }
    }
}

test_nested_fragment_container.xml is:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/content"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

</FrameLayout>

推荐答案

Yes, the onActivityResult() in nested fragment will not be invoked by this way.

The calling sequence of onActivityResult (in Android support library) is

  1. Activity.dispatchActivityResult()美元.
  2. FragmentActivity.onActivityResult().
  3. Fragment.onActivityResult()

在第三步中,在亲本Activity的第FragmentMananger个中找到该片段.因此,在您的示例中,发现要分派onActivityResult()的容器片段,嵌套的片段永远不会收到事件.

I think you have to implement your own dispatch in ContainerFragment.onActivityResult(), find the nested fragment and invoke pass the result and data to it.

Kotlin相关问答推荐

为什么try 在字符串列表上调用IterableInt.sum()失败,并抱怨无法转换为java.lang.Number?

如何在Kotlin的嵌套作用域中解析对此的引用

如何在Kotlin中为两个数据类创建可重用的方法?

Groovy Gradle文件的Kotlin类似功能

Kotlin 说不需要强制转换,但删除后会出现新警告

列表在 android WebView 中没有正确迭代

使用空键映射获取

Kotlin 使用委托进行隐式覆盖

嵌套数组 indexOf()

将多个 Kotlin 流合并到一个列表中,而无需等待第一个值

Kotlin not nullable值可以为null吗?

Kotlin 扩展函数 - 覆盖现有方法

Kotlin Native如何将字节数组转换为字符串?

如何在特定条件下清除jetpack数据存储数据

TypeConverter()在Android的TypeConverter错误中具有私有访问权限

具有泛型param的Kotlin抽象类和使用类型param的方法

将字符串转换为HashMap的最简单方法

Kotlin内联属性的用例是什么?

Kotlin:测试中的 java.lang.NoSuchMethodError

为什么 Kotlin 会收到这样的 UndeclaredThrowableException 而不是 ParseException?