Fragmentで起動したアクティビティから結果を受け取る方法

アクティビティに紐づくFragment内から別アクティビティを起動し結果を取得する方法にちょっと混乱したので備忘録てきにメモ。

Fragmentからアクティビティを起動するには普通 startActivity())にIntentを渡す方法がある。これは単純なアクティビティの起動だが、起動したアクティビティで何らかの処理が終わったタイミングで、Fragmentで結果を取得したい(そしてまた別の処理を開始したい)場合が多々ある。

例えば、ブログアプリでは、写真一覧画面で写真をタップしてその写真を投稿し、投稿結果を受け取りたい等。

そんな時に用いるのが startActivityForResult())である。簡単に説明すると、このメソッドにより別のアクティビティを起動し、Fragmentが紐付いてるアクティビティ側でonActivityResult())メソッドをOverrideして結果を受け取りなんらかの処理を実行する。

アクティビティを開始する

startActivityForReult()には、使用するIntentオブジェクトと追加で整数の引数を渡す。 この整数の引数は、システムがリクエストを識別するための「要求コード」となっている。結果のIntentを受け取り、アプリが要求コードを識別し、その処理方法を決定できるように、コールバックが同じ「要求コード」を提供する。

public class MainActivity extends Activity {
     public static final int REQUEST_CODE_FROM_PICTURE_LIST = 1; // システムが識別するためのrequest code
     ....
}

// PictureListFragmentはMainActivityにAttacthされてる
public class PictureListFragment extends Fragment {
    private void pickPicture() {
        Intent intent = BlogEditActivity.newIntent(getContext(), picturePath); // 使用するIntentを生成する
        startActivityForResult(intent, MainActivity.REQUEST_CODE_FROM_PICTURE_LIST); // MainActivityのstartActivityForResult()を呼び出し要求コードを渡す 
    }
}

起動したアクティビティから結果を受け取る

別のアクティビティを終えて復帰すると、システムはそのアクティビティ(BlogEditActivity)を起動した呼び出し元のアクティビティ(MainActivity)のonActivityResult()メソッドを呼び出す。

このメソッドには3つの引数を渡す。

  • startActivityForResult()に渡した「要求コード」
  • 起動した別のアクティビティ(BlogEditActivity)によって指定された「結果コード」(下記の2つのいずれか)
    • RESUT_OK: 操作が成功した
    • RESUT_CANCELED: ユーザがバックアウトしたり、なんらかの理由で操作が失敗した
  • 結果のデータを運ぶためのIntent

例:ブログを投稿するIntent用に結果を処理する方法について

public class PictureListFragment extends Fragment {
    ....
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_FROM_PICTURE_LIST) {
            if (resultCode == RESULT_OK) {
                // ブログ詳細のFragmentのコンストラクタに受け取ったdataをわたしてインスタンスを取得
                BlogDetailFragment toFragment = BlogDetailFragment.new(BlogEditActivity.getSavedResultBlogDetail(data));
                FragmentManager fm = getFragmentManager();
                FragmentTransaction transaction = fm.beginTransaction();
                transaction.replace(R.id.fragment_blog_detail_container, toFragment);
                transaction.addToBackStack(null);
                // ブログ詳細フラグメントに切り替える
                transaction.commit();
            }
        }
    }
}

正常に結果を処理するためには、結果のIntentの形式がどうなっているかを理解する必要がある。 今回は結果を返すアクティビティがBlogEditActivityのみなので、ブログを識別するためのid等が入ったdataを元に詳細画面を描画するくらいのことしかやっていない。複数のアクティビティが結果を返すようになると、要求コードに基づいてdataがどういった形式で渡ってきて、それを処理するべきか考える必要がある (画像データ、文字列、時刻..etc)。

Homebrewでインストールしたソフトにsymlinkを貼れないとき

ほんとに小さいけどハマったのでメモ。

作業効率をあげたくてtmux をインストールしたけど、tmux って打ってもcommand not foundになっていた。さくっと調べたら記事見つけたのでそのように↓解決。

 

stackoverflow.com

 

sudo chown -R $(whoami):admin /usr/local してbrewしたユーザーに/usr/bin以下に書き込む権限を与えてあげればいい。