LoginSignup
1
1

More than 5 years have passed since last update.

kotlinでAlertDialog with Custom Viewを使うときにはまったこと

Posted at

kotlin-android-extensionsって?

findViewByIdを使用せずともxmlファイルとkotlinソースコード間でのビューの関連付けを行ってくれるようになり、

MainActivity.java
Button button = (Button)findViewById(R.id.button)

こんなことをひたすらにしていたJavaとはおさらばし、
xmlで指定したidのままkotlinソースコード上で使えるという割と便利なプラグイン

今回は、そのことに気づかずにAlertDialogでハマってしまったので、メモ程度に残しておきたいと思います。

何にハマったのか

dialog_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />

</LinearLayout>
MainActivity.kt
/* 
package、インポートなどは省略
*/

class MainActivity : AppCompatActivity(), View.OnClickListener {

    private val TAG: String = "MainActivity"

    private val mContext: Context = this

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.time_table_activity)

        button.setOnClickListener(mContext)
    }

    override fun onClick(view: View?) {
        // customViewとなるViewをinflateして作成
        val customLayout = layoutInflater.inflate(R.layout.component_time_table_dialog, null)
        // inflateしてできたViewから、リソースID参照してEditTextを指定する
        val editText: EditText = customLayout.findViewById(R.id.editText)
        // Builderメソッドで、AlertDialogをビルドする
        AlertDialog.Builder(mContext).apply {
            setView(customLayout)
            setTitle("AlertDialogTutorial")
            setPositiveButton("ACCEPT", DialogInterface.OnClickListener { dialogInterface, which ->
                Toast.makeText(mContext, subject.text.toString(), Toast.LENGTH_SHORT).show()
            })
            setNegativeButton("REJECT", null)
            show()
        }
    }
}

こちらが、最終的に完成したコードのサンプルバージョンです。
実際にどこにハマったかというと、

MainActivity.kt
editText: EditText = customLayout.findViewById(R.id.editText)

の部分ですね、

kotlin-android-extensions

を使っていたので最初はxmlファイルから直接(findViewByIdメソッドを使わず)editTextを用いていました。
しかし、それでは、component_time_table_dialog.xmlから参照しているだけで、AlertDialogのCustomViewとして用いるViewの方からは参照していなかったみたいで、常にIllegalStateExceptionを吐かれました。

考えてみれば、当たり前のことでしたが、同じ過ちを侵さないためにもメモとして残しておきます。
inflateしたViewからはkotlin-android-extensionsは参照しないので、注意してください。
AlertDialogのCustomViewとしてinflateしたViewの方から参照してあげないとエラーを吐かれます。

最後に

kotlin-android-extensionsを初めて使ってみてハマったエラーなので、何言ってんだこんなの当たり前じゃないかというお声もあるかもしれません…コードの改善点等ございましたらご指摘お願いいたします。もし今回の投稿が誰かのお役に立てましたら幸いです(_ _)

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1