前提・実現したいこと
ListViewがあり、文字列を格納したリストとArrayAdapterで連携しているとします。
また、ListViewの項目をタップした際にアイテムを削除して画面を更新するとします。
上記を実現するために、リスナを設定する際にアダプターを取得し処理を記述する必要があるのですが、取得したアダプターの型のチェックやキャストをする正しい方法がわかりません。
asを用いて型変換を行うとコンパイルは通り、アプリは正常に動作するのですが以下の警告が出ます。
警告
Unchecked cast: Adapter! to ArrayAdapter<String>
もちろん最初にリストビューにリストを設定する際に宣言し使用したアダプターをリスナ内で使えば警告なしでコンパイルすることはできるのですが、リスナを設定する際にparent.adapterで取得したアダプターを使って記述する方法が知りたくて質問させていただきました。
よろしくおねがいします。
該当のソースコード
Kotlin
1class MainActivity : AppCompatActivity() { 2 3 override fun onCreate(savedInstanceState: Bundle?) { 4 super.onCreate(savedInstanceState) 5 setContentView(R.layout.activity_main) 6 7 val list = mutableListOf("アイテム1", "アイテム2", "アイテム3") 8 val adapter = ArrayAdapter<String>(applicationContext, android.R.layout.simple_list_item_1, list) 9 lv.adapter = adapter 10 11 lv.setOnItemClickListener { parent, view, position, id -> 12 val adapter = parent.adapter as ArrayAdapter<String> 13 adapter.remove(adapter.getItem(position)) 14 adapter.notifyDataSetChanged() 15 } 16 17 } 18 19}
試したこと
isを用いた場合は以下のエラーが出ました。parent.adapterの返り値がAdapter!のため中身の型情報を持っていないことが原因と考えられます。
Kotlin
1lv.setOnItemClickListener { parent, view, position, id -> 2 val adapter = parent.adapter 3 if(adapter is ArrayAdapter<String>) { 4 adapter.remove(adapter.getItem(position)) 5 adapter.notifyDataSetChanged() 6 } 7 }
エラー
Cannot check for instance of erased type
次にArrayAdapter<*>として型のチェックを行うとadapter.removeに渡す引数のところでエラー出ました。
Kotlin
1lv.setOnItemClickListener { parent, view, position, id -> 2 val adapter = parent.adapter 3 if(adapter is ArrayAdapter<*>) { 4 adapter.remove(adapter.getItem(position)) 5 adapter.notifyDataSetChanged() 6 } 7 }
エラー
Type mismatch: inferred type is Any! but Nothing! was expected. Projected type ArrayAdapter<*> restricts use of public open fun remove(@RecentlyNullable p0: T!): Unit defined in android.widget.ArrayAdapter
parent.adapterを使用する際、どのように実装すれば警告、エラー無しで実装できるのでしょうか?
それとも、そもそもリスナ設定内でparent.adapterを用いて処理を書くことが書き方的に間違っているのでしょうか?