別画面(サブアクティビティ)へ遷移した後、その内容をメイン画面(メインアクティビティ)で受け取る方法を紹介します。前記事では、画面遷移時に値を渡す方法を紹介していますので、そちらを先に見た方が理解がしやすいと思います。
画面遷移先から値を受け取るためのポイント
メインからサブアクティビティに値を渡す画面遷移の方法を以下記事で紹介しています。その方法を知らない人はまずこちら。
上記方法と異なる点は、startActivity()ではなくgetResult.launch()でサブアクティビティへ遷移します。
また追加すべき内容としては、以下の二つ。
- パブリックなキー(EXTRA_MESSAGE)
- サブアクティビティから値を受け取るためのregisterForActivityResult
サンプルコード(Kotlin)
以下のようなサンプルを作成しました。
動作は以下の通り。
- メインアクティビティのEditTextへ文字入力し、ボタンを押してサブアクティビティへ遷移。
- メインアクティビティからのテキストを、サブアクティビティで受け取りEditTextに表示する。
- 受け取ったテキストをEditTextで編集し、ボタンを押してサブアクティビティを閉じる。
- メインアクティビティに編集後のテキストが表示される。
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)を複数用意すればできます。
コメント