Androidプログラミング

【Android】画面遷移先から値を受け取る方法【Kotlin】

Androidの遷移先要素受け取り記事のアイキャッチ画像 Android

別画面(サブアクティビティ)へ遷移した後、その内容をメイン画面(メインアクティビティ)で受け取る方法を紹介します。前記事では、画面遷移時に値を渡す方法を紹介していますので、そちらを先に見た方が理解がしやすいと思います。

スポンサーリンク

画面遷移先から値を受け取るためのポイント

メインからサブアクティビティに値を渡す画面遷移の方法を以下記事で紹介しています。その方法を知らない人はまずこちら。

上記方法と異なる点は、startActivity()ではなくgetResult.launch()でサブアクティビティへ遷移します。

また追加すべき内容としては、以下の二つ。

  • パブリックなキー(EXTRA_MESSAGE)
  • サブアクティビティから値を受け取るためのregisterForActivityResult
スポンサーリンク

サンプルコード(Kotlin)

以下のようなサンプルを作成しました。

画面遷移と要素受け取りの様子
サンプルアプリの動作の様子

動作は以下の通り。

  1. メインアクティビティのEditTextへ文字入力し、ボタンを押してサブアクティビティへ遷移
  2. メインアクティビティからのテキストを、サブアクティビティで受け取りEditTextに表示する。
  3. 受け取ったテキストをEditTextで編集し、ボタンを押してサブアクティビティを閉じる。
  4. メインアクティビティに編集後のテキストが表示される

MainActivity

xmlは以下の通り。
文字入力用のEditText(SubActivityからの文字受け取りもここ)、画面遷移用のボタンがあります。

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="30dp"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#ff0"
        android:text="Value to SubActivity:"/>
    <!-- 入力・表示用 -->
    <EditText
        android:id="@+id/etInput"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <!-- 画面遷移用ボタン -->
    <Button
        android:id="@+id/btGosub"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Go SubActivity"
        android:layout_gravity="center" />

</LinearLayout>

Kotlinは以下の通り。

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    // サブアクティビティから要素受け取る用
    companion object{
        const val EXTRA_MESSAGE ="com.example.subactivity00.MESSAGE"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)

        //ボタンのインスタンス
        val btnListener = BtnListener()
        //ボタンにリスナ追加
        binding.btGosub.setOnClickListener(btnListener)
    }

    //リスナクラス
    private inner class BtnListener:View.OnClickListener{

        override fun onClick(v: View) {
            
            val intent = Intent(this@MainActivity,SubActivity::class.java)

            // 渡す値をIntentに格納
            intent.putExtra(EXTRA_MESSAGE, binding.etInput.text.toString())

            // サブアクティビティを起動
            receiveResult.launch(intent)
        }
    }

    // SubActivityから受け取る用
    private val receiveResult =
        registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()
        ) {
            if (it.resultCode == Activity.RESULT_OK) {
                val res = it.data?.getStringExtra(EXTRA_MESSAGE)
                binding.etInput.setText(res)
            }
        }
}

ボタンのクリック処理はリスナクラスに記載しています。その方が個人的には見やすいと思うので。

SubActivity

xmlは以下の通り。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="30dp"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#0f0"
        android:text="From MainActivity" />
    <!--受け取り・編集用-->
    <EditText
        android:id="@+id/etSub"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <Space
        android:layout_width="wrap_content"
        android:layout_height="20pt"/>

    <!--サブアクティビティ終了用ボタン-->
    <Button
        android:id="@+id/btBackMain"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="Back to MainActivity" />

</LinearLayout>

Kotlinは以下の通り。

class SubActivity :AppCompatActivity(){

    private lateinit var binding: ActivitySubBinding

    override fun onCreate(savedInstanceState: Bundle?){
        super.onCreate(savedInstanceState)

        binding = ActivitySubBinding.inflate(layoutInflater)
        var view = binding.root
        setContentView(view)

        // Mainからの変数受け取り
        val fromMain_text = intent.getStringExtra(MainActivity.EXTRA_MESSAGE)
        binding.etSub.setText(fromMain_text)

        // ボタンのインスタンス
        val btnListener_sub = BtnListenersub()
        // ボタンにリスナを追加
        binding.btBackMain.setOnClickListener(btnListener_sub)

    }

    //ボタンのリスナクラス
    private inner class BtnListenersub:View.OnClickListener{

        override fun onClick(v: View) {
            Toast.makeText(applicationContext, "Back to Main with:"+binding.etSub.text, Toast.LENGTH_SHORT).show()

            //テキスト取得
            val txt:String = binding.etSub.text.toString()

            // インテント作成
            val intentSub = Intent()

            intentSub.putExtra(MainActivity.EXTRA_MESSAGE, txt)
            setResult(Activity.RESULT_OK, intentSub)

            // アクティビティを終了
            finish()
        }
    }
}
スポンサーリンク

さいごに

画面遷移が使いこなせるだけで一気に幅が広がりますね。

複数の要素をサブアクティから受け取りたい場合は、メインアクティビティにてキー(EXTRA_MESSAGE)を複数用意すればできます。

コメント

タイトルとURLをコピーしました