かなり簡単なシナリオがあり、かなりのトラブルを引き起こしています。フラグメントを埋め込んだ非常にシンプルなアクティビティを作成しています。このフラグメントは、単にいくつかの画像を表示するグリッドビューです。この問題は、Kotlin拡張機能を使用してGridviewを参照し、XML IDを直接参照するときに発生します。 ここでの問題は何ですか?kotlinxは静的フラグメントでは動作しませんか?
エラー:
Java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.Android.android_me/com.example.Android.android_me.ui.MainActivity}: Java.lang.IllegalStateException: gridview_all_parts must not be null
Caused by: Java.lang.IllegalStateException: gridview_all_parts must not be null at com.example.Android.android_me.ui.MasterListFragment.onActivityCreated(MasterListFragment.kt:22)
攻撃的なコード行を含むフラグメント
import kotlinx.Android.synthetic.main.fragment_master_list.*
class MasterListFragment: Fragment() {
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val layoutView = inflater?.inflate(R.layout.fragment_master_list, container, false)
return layoutView
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
//If this is removed, code runs
gridview_all_parts.adapter = MasterListAdapter(activity, AndroidImageAssets.getAll())
super.onActivityCreated(savedInstanceState)
}
}
フラグメントレイアウト:
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/gridview_all_parts"
Android:layout_width="match_parent" Android:layout_height="match_parent"/>
親アクティビティレイアウト
<?xml version="1.0" encoding="utf-8"?>
<!--have tried both class:= and Android:name:=-->
<fragment xmlns:Android="http://schemas.Android.com/apk/res/Android"
class="com.example.Android.android_me.ui.MasterListFragment"
Android:id="@+id/fragment_masterlist"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
/>
親の活動
class MainActivity: AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
Fragmentで拡張機能を使用するには、layoutView
で使用する必要があります。これは動作するはずです:layoutView.gridview_all_parts.adapter = MasterListAdapter(activity, AndroidImageAssets.getAll())
この場合、layoutViewをグローバルにすることができます。
UPDATED EXPLANATIONビューの膨張と関係があります。 butterknifeのように、fragment/recyclerViewの場合は膨張したビューをバインドする必要があります。同様にkotlinの場合は、xmlのビューにアクセスするためにその膨張ビューが必要です。
公式ドキュメント から引用
合成プロパティのインポート特定のレイアウトのすべてのウィジェットプロパティを一度にインポートすると便利です。
import kotlinx.Android.synthetic.main.<layout>.*
したがって、レイアウトファイル名が
activity_main.xml
、インポートしますkotlinx.Android.synthetic.main.activity_main。*。
Viewで合成プロパティを呼び出す場合は、インポートする必要があります
kotlinx.Android.synthetic.main.activity_main.view.*.
これを行うと、対応する拡張機能を呼び出すことができます。拡張機能は、XMLファイルのビューにちなんで名付けられたプロパティです。
他のケースでこの問題を発見したすべての人に。
Android ExtensionsからのNPEは、RecyclerViewのアダプターを作成するときにも発生します(特に:CustomViewHolderの作成)。
詳細およびこの問題の修正方法については、 LayoutContainer を参照してください。
apply plugin: 'kotlin-Android-extensions'
Android {
androidExtensions {
experimental = true
}
// your config
defaultConfig {}
}
class MainViewHolder(override val containerView: View) :
RecyclerView.ViewHolder(containerView),
LayoutContainer { // Extends this
fun bind(item: News) = containerView.apply {
tv_item_title.text = item.title
}
}