1. ホーム
  2. java

新しいネストされたフラグメントAPIでonActivityResult()が呼ばれない

2023-08-07 13:45:35

質問

私はこれまで、新しい ネストされたフラグメント API が Android のサポート ライブラリに含まれています。

ネストされたフラグメントで直面している問題は、ネストされたフラグメント (つまり、他のフラグメントに FragmentManager が返す getChildFragmentManager() ) の呼び出し 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>

どのように解決するのですか?

そうです。 onActivityResult() はこの方法では呼び出されません。

onActivityResultの呼び出し順序(Androidサポートライブラリ内)は以下の通りです。

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

3番目のステップでは、フラグメントは FragmentMananger の親 Activity . つまり、この例では、ディスパッチするために見つかったコンテナフラグメントは onActivityResult() であり、ネストされたフラグメントはイベントを受け取ることができません。

で独自のディスパッチを実装する必要があると思います。 ContainerFragment.onActivityResult() で、ネストしたフラグメントを見つけて呼び出し、結果とデータを渡す必要があります。