Androidアプリ開発入門:画面遷移を実装する
AndroidのアプリをAndroid Studioで作っています。今回は画面遷移を実装してみようと思いました。画面遷移はActivityの遷移で発生し、遷移自体はIntentを使って実現できます。ただ、Activityの前後でデータをやり取りしようとすると一つ処理を挟む必要が出てきます。それがstartActivityForResultです。
実際に書いてみました。
![](https://assets.st-note.com/img/1639055262323-u92mZUqnbC.png)
おっと、なぜか取り消し線が引かれてしまいました。どういうことかとクリックしてみると
![](https://assets.st-note.com/img/1639055357655-rdm8udKKjY.png)
Deprecate(非推奨)となっていました。実際、2020年の2月には既に新しい方法が提示されていたそうです。
では何を使うのかというと、ActivityResultLauncher です。
こんな感じで変数を定義し、
val startforRes = registerForActivityResult(ActivityResultContracts.StartActivityForResult())
{
result ->
if (result.resultCode != RESULT_OK){}
val resstr = result.data?.getStringExtra(act1.ResultExtr.MESSAGE.name)
binding.textview.text = resstr
}
startforRes.launch(intent)
で遷移させます。
これをビルドするとこんなエラーが。
java.lang.IllegalStateException: LifecycleOwner com.example.mytrial.MainActivity@61d557e is attempting to register while current state is RESUMED. LifecycleOwners must call register before they are STARTED.
どうやら、ライフサイクルにおいて、Startedする前に定義しないといけないみたいです。実際、onCreateの中で定義していたものを、次のように外出しすることでエラーを回避しました。
val startforRes = registerForActivityResult(ActivityResultContracts.StartActivityForResult())
{
result ->
if (result.resultCode != RESULT_OK){}
val resstr = result.data?.getStringExtra(act1.ResultExtr.MESSAGE.name)
binding.textview.text = resstr
}
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
var counter = 0
setContentView(binding.root)
val rootLayout: View = findViewById(android.R.id.content)
val snackbar = Snackbar.make(rootLayout , "Snackbar message", Snackbar.LENGTH_LONG)
snackbar.setAction("Touch me"){
binding.textview.text = "You touched!"
}
snackbar.show()
binding.button1.setOnClickListener{
counter++
binding.textview.text = counter.toString()
val snackbar2 = Snackbar.make(rootLayout , counter.toString(), Snackbar.LENGTH_LONG)
.setAction("Undo") {
counter--
binding.textview.text = "Minused $counter"
}.show()
}
binding.button2.setOnClickListener{
val intent = Intent(applicationContext, act1::class.java)
val str = binding.editText1.text
intent.putExtra(MY_MSG, binding.editText1.text.toString())
startforRes.launch(intent)
}
}
}
アクティビティの遷移前後でデータをやり取りする箇所が、putExtra(MY_MSG, binding.editText1.text.toString())
です。このコードのうち、最後のtoString()をつけ忘れるとString型でデータが送られないため、受取先で文字が表示できませんでした。
ちなみに、受取先のコードはこちら。
private lateinit var binding: ActivityAct1Binding
class act1 : AppCompatActivity() {
enum class ResultExtr {
MESSAGE
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityAct1Binding.inflate(layoutInflater)
setContentView(binding.root)
val getstr = intent.getStringExtra(MainActivity.MY_MSG)
binding.textView21.text = getstr
binding.button.setOnClickListener{
finishActivity()
}
}
fun finishActivity(){
val intent = Intent().apply {
putExtra(ResultExtr.MESSAGE.name, "hei")
}
setResult(RESULT_OK, intent)
finish()
}
}
遷移先から遷移元にデータを渡すには、 Intent().apply { putExtra(ResultExtr.MESSAGE.name, "hei") } のようにapplyの中でputExtraを呼びます。
この記事が気に入ったらサポートをしてみませんか?