Table of Contents
AndroidアプリのレイアウトをXMLファイル(activity_main.xml)で設定している場合、あるウィジェットやレイアウトなどのUI要素を継承した「拡張UI要素」を配置しようとして以下のエラーが発生することがあります。
android.view.InflateException: Binary XML file line #0: Binary XML file line #0: Error inflating class [クラス名]
これは、継承して作ったUI要素のクラスに書くべきコンストラクタが足りていないことが原因となります。実際のプログラムを例に原因と解決方法を紹介します。
InflateExceptionが起こるプログラム
以下のような Kotlin のプログラムとレイアウト用XMLでアプリが作られているとします。
MainActivity.kt
package com.example.test.testproject import android.content.Context import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.util.Log import android.view.View class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } } class MyView(context: Context?) : View(context) { init { Log.i("debug", "継承して作ったView") } }
クラス MyView が View を継承して作った拡張UI要素です。第1コンストラクタ(プライマリコンストラクタ)のみを定義しています。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.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="com.example.test.testproject.MainActivity"> <com.example.test.testproject.MyView android:layout_width="match_parent" android:layout_height="match_parent" /> </android.support.constraint.ConstraintLayout>
拡張したUI要素(com.example.test.testproject.MyView)を配置しています。
プログラムで定義したUI要素をXMLファイルで配置する場合は、パッケージ名も含めたフルネームで記述します。
以上のファイルからなるアプリを実行してみると「InflateException」が発生し、アプリが強制終了します。
この原因は MainActivity.kt の MyView にコンストラクタの定義が足りないことです。プライマリコンストラクタ(第一コンストラクタ)だけでなく、あと2つコンストラクタを定義する必要があります。
この3つのコンストラクタを継承したクラスに定義します。
修正されたプログラム
MainActivity.kt の MyView を以下のように修正します。
...(略)... class MyView : View { constructor(context: Context): super(context) { Log.i("debug", "継承して作ったView コンストラクタ1") } constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet) { Log.i("debug", "継承して作ったView コンストラクタ2") } constructor(context: Context, attributeSet: AttributeSet, defStyle: Int) : super(context, attributeSet, defStyle) { Log.i("debug", "継承して作ったView コンストラクタ3") } }
XMLレイアウトの修正は必要ありません。
修正後、プログラムを実行してみると問題なく動作し、コンソールには第2コンストラクタが呼ばれたことが確認できるログが表示されます。
おしまい
上記の例ではプログラムの言語が Kotlin でしたが、言語が Java の場合でも原因と解決方法は同じです。
また、今回は親となるUI要素が View でしたが、ラベル(TextView)やテキストエリア(EditText)のような別のUI要素でも同様です。