代码之家  ›  专栏  ›  技术社区  ›  Josh Ribeiro

Kotlin Android扩展提供布局空指针

  •  22
  • Josh Ribeiro  · 技术社区  · 7 年前

    有一个相当简单的场景给我带来了不少麻烦。我正在用一个嵌入的片段做一个非常简单的活动。这个片段只是一个显示一些图像的Gridview。当使用Kotlin扩展直接引用XML id引用Gridview时,就会出现问题。 这里的问题是什么? 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)
        }
    }
    
    2 回复  |  直到 7 年前
        1
  •  30
  •   karandeep singh    7 年前

    要在片段中使用扩展,您需要使用 layoutView . 这应该可以: layoutView.gridview_all_parts.adapter = MasterListAdapter(activity, AndroidImageAssets.getAll())

    在这种情况下,可以将布局视图设置为全局。

    更新的说明 这与视图膨胀有关。与butterknife一样,在fragment/recyclerView的情况下,我们需要绑定膨胀视图,在kotlin的情况下,我们同样需要膨胀视图来访问xml中的视图。

    引用自 official documentation ,

    导入合成属性可以方便地一次性导入特定布局的所有小部件属性:

    import kotlinx.android.synthetic.main.<layout>.*

    因此,如果布局文件名为 activity_main.xml ,我们将导入

    科特林克斯。安卓合成的主要的activity\u main。*。

    如果我们想将合成属性称为视图,我们还应该 进口

    kotlinx.android.synthetic.main.activity_main.view.*.

    一旦我们这样做了,我们就可以调用相应的扩展, 它们是以XML文件中的视图命名的属性。

        2
  •  0
  •   mochadwi    6 年前

    对于在另一个案例中发现此问题的所有人。

    当我们为RecyclerView编写适配器时(尤其是:编写CustomViewHolder),也会出现来自Android扩展的NPE。

    看见 LayoutContainer 有关详细信息以及如何解决此问题。

    1. 将此添加到模块级渐变中
    apply plugin: 'kotlin-android-extensions'
    
    android {
        androidExtensions {
            experimental = true
        }
        // your config
        defaultConfig {}
    }
    
    1. 您的适配器
    class MainViewHolder(override val containerView: View) :
        RecyclerView.ViewHolder(containerView), 
        LayoutContainer { // Extends this
            fun bind(item: News) = containerView.apply {
                tv_item_title.text = item.title
            }
    }