onActivityResult() 未在新嵌套片段 API 中调用

我一直在使用Android包含在支持库中的新嵌套片段API。

我面临的嵌套片段的问题是,如果嵌套片段(即通过返回的)添加到另一个片段的片段调用 ,则不会调用嵌套片段的方法。但是,父片段和活动都会被调用。FragmentManagergetChildFragmentManager()startActivityForResult()onActivityResult()onActivityResult()onActivityResult()

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

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是:

<?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>

答案 1

我用下面的代码解决了这个问题(使用支持库):

在容器片段中,覆盖 onActivity以这种方式结果:

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

        List<Fragment> fragments = getChildFragmentManager().getFragments();
        if (fragments != null) {
            for (Fragment fragment : fragments) {
                fragment.onActivityResult(requestCode, resultCode, data);
            }
        }
    }

现在嵌套片段将接收对 onActivityResult 方法的调用。

此外,正如 Eric Brynsvold 在类似问题中指出的那样,嵌套片段应该使用它的父片段而不是简单的 startActivityForResult() 调用来启动活动。因此,在嵌套片段中,通过以下方式开始活动:

getParentFragment().startActivityForResult(intent, requestCode);

答案 2

是的,不会以这种方式调用 in 嵌套片段。onActivityResult()

onActivityResult(在 Android 支持库中)的调用顺序为

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

在第 3 步中,在 父项 中找到该片段。因此,在您的示例中,找到的容器片段是调度 ,嵌套片段永远无法接收事件。FragmentManangerActivityonActivityResult()

我认为您必须在 中实现自己的调度,找到嵌套片段并调用将结果和数据传递给它。ContainerFragment.onActivityResult()


推荐