Androidアプリ開発の教科書Kotlin対応 を参考にAndroidのアプリについて勉強しています
7章 画面遷移とIntentクラス ではまった
はまっていた当時のコード
目的の動作は上記の絵の通り。
ビルドは問題なくできているのに、、、
「から揚げ定食」を押した際のlogcatを見てみると、たくさんのエラーが、、、、 logcat
結果的に以下のエラーを読んだことが修正のきっかけになりました。
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.masashi.things.intentsample/com.masashi.things.intentsample.MenuThanksActivity}:
java.lang.IllegalStateException: tvMenuPrice must not be null
遷移したい先の「MenuThanksActivity」が見つからないみたい。。。
遷移したい先の「tvMenuPrice」がnullになっていることが原因で、「MenuThanksActivity」がスタートできないって言ってます。
※エラーの解釈について@linsks_2_3_4 さんからコメントをいただきました。
ありがとうございます!
https://qiita.com/manyou/items/1bce375100a11fc614b0#comment-4a7cb04c63f16065227e
MenuThanksActivity.kt を見てみると、以下のような文を発見
public class MenuThanksActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
MenuThanksActivity.kt を以下のように修正したら。。。。成功!!わーーい!!
public class MenuThanksActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_menu_thanks) #ここを変更!
setContentView は 引数に画面のレイアウトが書かれた~~~.xmlを指定するのだね、、、(笑)
超基本そう。。。
setContentView(R.layout.activity_menu_thanks)
↓↓↓↓↓ 以下は詳細 ↓↓↓↓↓
#logcat
I/System.out: masashi, から揚げ定食
W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@bae3899
I/System.out: masashimasashimasashi
W/masashi: masashi
I/System.out: masashi,800円
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.masashi.things.intentsample, PID: 19030
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.masashi.things.intentsample/com.masashi.things.intentsample.MenuThanksActivity}: java.lang.IllegalStateException: tvMenuPrice must not be null
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.IllegalStateException: tvMenuPrice must not be null
at com.masashi.things.intentsample.MenuThanksActivity.onCreate(MenuThanksActivity.kt:28)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
#code
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/lvMenu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
- AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.masashi.things.intentsample">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MenuThanksActivity"></activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
- activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/lvMenu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
- activity_menu_thanks.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:gravity="center"
android:text="@string/tv_thx_title"
android:textSize="25sp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="@string/tv_thx_desc"
android:textSize="15sp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/tvMenuName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"/>
<TextView
android:id="@+id/tvMenuPrice"
android:layout_width="243dp"
android:layout_height="wrap_content" />
</LinearLayout>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="onBackButtonClick"
android:text="@string/bt_thx_back"/>
</LinearLayout>
- strings.xml
<resources>
<string name="app_name">画面遷移サンプル</string>
<string name="tv_thx_title">注文完了</string>
<string name="tv_thx_desc">以下のメニューのご注文を受け付けました\nご注文ありがとうございます。</string>
<string name="bt_thx_back">リストに戻る</string>
</resources>
- MenuThanksActivity.kt
package com.masashi.things.intentsample
import android.nfc.Tag
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.masashi.things.intentsample.R
import kotlinx.android.synthetic.main.activity_menu_thanks.*
public class MenuThanksActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val menuName = intent.getStringExtra("menuName")
val menuPrice = intent.getStringExtra("menuPrice")
//val tvMenuName = findViewById<TextView>(R.id.tvMenuName)
val tvMenuName = findViewById<TextView>(R.id.tvMenuName)
val tvMenuPrice = findViewById<TextView>(R.id.tvMenuPrice)
println("masashimasashimasashi")
Log.w("masashi","masashi")
println("masashi,$menuPrice")
//TextViewに定食と金額を表示
tvMenuPrice.text = menuPrice
//tvMenuPrice.setText(String.valueOf(menuPrice))
tvMenuName.text=menuName
}
fun onBackButtonClick(view: View) {
Log.w("masashi","masashi")
finish()
}
}
- MainActivity.kt
package com.masashi.things.intentsample
import android.content.Intent
import android.net.sip.SipSession
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.AdapterView
import android.widget.ListView
import android.widget.SimpleAdapter
import androidx.core.content.ContextCompat.startActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val lvMenu = findViewById<ListView>(R.id.lvMenu)
val menuList: MutableList<MutableMap<String, String>> = mutableListOf()
//から揚げ定食のデータを格納するMapオブジェクトの用意とmenuListへのデータ登録
var menu = mutableMapOf("name" to "から揚げ定食", "price" to "800円")
menuList.add(menu)
menu = mutableMapOf("name" to "ハンバーグ定食", "price" to "850円")
menuList.add(menu)
val from = arrayOf("name", "price")
val to = intArrayOf(android.R.id.text1, android.R.id.text2)
//SimpleAdapterを生成
val adapter = SimpleAdapter(applicationContext, menuList, android.R.layout.simple_list_item_2, from, to)
lvMenu.adapter = adapter
lvMenu.onItemClickListener = ListItemClickListener()
}
private inner class ListItemClickListener : AdapterView.OnItemClickListener {
override fun onItemClick(parent: AdapterView<*>, view: View, position: Int, id: Long) {
val item = parent.getItemAtPosition(position) as MutableMap<String, String>
//定食名と金額を取得
val menuName = item["name"]
val menuPrice = item["price"]
//intent オブジェクトを生成
val intent = Intent(applicationContext, MenuThanksActivity::class.java)
//第二画面に送るデータを格納
intent.putExtra("menuName", menuName)
intent.putExtra("menuPrice", menuPrice)
println("masashi, $menuName")
//第二画面の起動
startActivity(intent)
}
}
}