NextLeap blog

【Android】画面間のデータ受け渡し方法いろいろ

Fragment Instance、Bundle, コールバックリスナー、onActivityResultについてまとめてみました


画面間でデータを受け渡ししたいと思うことはよくあると思います。その方法を4つ紹介します。

① Fragment Instance引数渡し

まずは、普通に使っているであろうものから。Fragmentとして画面を開く場合に下記のように new で開くと何も渡せません。

	
    FragmentManager manager = getSupportFragmentManager();
     FragmentTransaction transaction = manager.beginTransaction();
     Fragment fragment = new SampleFragment();
     transaction.replace(R.id.content, fragment);
     transaction.addToBackStack(null);
     transaction.commit();
				    

これを、次のように newInstance( param1, param2, param3 ) として開くことで、パラメータを渡すことができます。これによって、同じFragmentでも、状況に応じて異なる結果を表示させることができます。

	
    FragmentManager manager = getSupportFragmentManager();
     FragmentTransaction transaction = manager.beginTransaction();
     Fragment fragment = SampleFragment.newInstance( param1, param2, param3 );
     transaction.replace(R.id.content, fragment);
     transaction.addToBackStack(null);
     transaction.commit();
				    
 

② Intentによるbitmap渡し

ある画面でバックエンドからbitmapを取得したとします。クリックして、詳細データを表示するような画面構成の場合、クリック後の画像はどう準備したらよいでしょうか?バックエンドのパスを①のFragment Instance引数に渡し、再度バックエンドから取得することもできるでしょう。画像をローカルに保存しておき、そのパスを渡すことで、ローカルから取得することもできるでしょう。ここで紹介するのは、画像をBundleに入れて渡す方法です。この方法だとシンプルに渡すことができます

	
        Bundle bundle =  new Bundle();
        Bitmap bmp = ((BitmapDrawable) {ImageView}.getDrawable()).getBitmap();
        bundle.putParcelable("param", bmp);
				    

{ImageView}←ここには、Bitmapを表示しているImageViewを指定します。上記は、すでにImageViewに表示されている画像を取得し、Bundleにつめて①のFragment Instance引数でbundleを渡すことができます。bitmapはParcelableというインタフェースを持っているので可能なのです。なお、Parcelable インタフェースをクラスにつけることで、クラスごと渡せたりするようです。org.parceler:parceler-apiを利用することで@Parcelというアノテーションを追加するだけで良いとのこと。素晴らしい。

③ コールバックリスナーで受け渡し、というか通知

呼び出し側でコールバックインタフェースを定義し、呼び出します。呼び出される側では、呼び出し側のインタフェースをimplemnetsし、インタフェースの実装を行います。こうすることで、インタフェースのパラメータを呼び出される側で使用できます。というか再描画してね、とか通知するのによく使います。

インタフェースの定義
	
    public interface OnOkClickListener {
        public void onOkClicked(Bundle args);
    }
				    
呼び出される側のコールバック関数参照設定
	
    private OnOkClickListener mListener;
    mListener =(OnOkClickListener) {呼び出される側のfragment};
				    
コールバック関数の呼び出し
	
    Bundle arg = new Bundle();
    arg.putString("KEY", "SAMPLE");
    arg.putInt("ITEM_KEY", 100);
    mListener.onOkClicked(arg);
				    
呼び出される側のコールバック関数参照設定
	
    public void onOkClicked(Bundle args) {

        String str = args.getString("KEY");

        switch (str){

            case "SAMPLE":
                Integer sample = args.getInt("ITEM_KEY");
                break;

        }
    }
				    

④ onActivityResult

ActivityやDialogを呼び出した場合に、呼び出し先の処理完了時に戻りを取得することができます。ここでは、呼び出し元のFraと呼び出されるDialog間でのデータ受け渡しを説明します。この場合でもDialogの生成では①と同じくStaticなnewInstanceを呼び出します。この時、戻りを返すFragmentを渡すことが重要です。リクエストコードについては、識別できる任意の値にしておきましょう

	
    public static SampleFragment newInstance(Fragment target, int requestCode, String param1, String param2, int param3) {
        SampleFragment fragment = new SampleFragment();
        fragment.setTargetFragment(target, requestCode);
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        args.putInt(ARG_PARAM3, param3);
        fragment.setArguments(args);
        return fragment;
    }
				    

呼び出されたDialog側では、DialogのOKボタンクリック時に戻したいデータをIntentに詰め込み、呼び出し元のonActivityResultを呼び出します

	
        Fragment target = getTargetFragment();
        if (target == null) { return; }

        Intent data = new Intent();
        data.putExtra(Intent.EXTRA_USER, hogehoge1);
        data.putExtra(Intent.EXTRA_TEXT, hogehoge2);
        data.putExtra(Intent.EXTRA_SUBJECT, hogehoge3);
        target.onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, data);
				    

呼び出した側では、onActivityResultの実装を記述しておくことで、Dialogでの結果を利用することが可能になります

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

        switch (requestCode) {
            case 0:
                if (resultCode != Activity.RESULT_OK) { return; }

        // ここに処理を記述します

                return;

        }
        super.onActivityResult(requestCode, resultCode, data);
   }
				    

画面間でのデータ渡しについて、少しは参考になったでしょうか(^^)