【问题标题】:Kotlin Android Extensions giving Layout Null PointerKotlin Android Extensions 提供布局空指针
【发布时间】:2018-02-16 15:34:05
【问题描述】:

有一个相当简单的场景给我带来了很多麻烦。我正在使用嵌入式片段制作一个非常简单的活动。这个片段只是一个显示一些图像的 Gridview。当使用 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 类,而不仅仅是“攻击性代码”吗?
  • 嘿汤姆,这就是整个代码。这是我正在尝试“Kotlinize”的简单教程的一部分,因此是基本结构

标签: android android-fragments kotlin-android-extensions


【解决方案1】:

要在 Fragment 中使用扩展,您需要使用 layoutView。 这应该有效:layoutView.gridview_all_parts.adapter = MasterListAdapter(activity, AndroidImageAssets.getAll())

在这种情况下,您可以将 layoutView 设为全局。

更新说明 它与视图膨胀有关。就像在butterknife中一样,我们需要在fragment/recyclerView的情况下绑定inflated view,在kotlin的情况下,我们需要那个inflate view来访问xml中的视图。

引用official documentation

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

import kotlinx.android.synthetic.main.&lt;layout&gt;.*

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

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

如果我们想在 View 上调用合成属性,我们还应该 进口

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

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

【讨论】:

  • 成功了!你介意解释一下为什么在这个例子中 layoutInflater 需要引用 View 对象而不是其他场景吗?一旦你这样做,我会将此标记为答案。再次感谢!
  • @JoshRibeiro 当我们编写适配器时,RecyclerView 也会出现这个问题。发现此问题的每个人都可能想阅读有关 LayoutContainer 的内容
【解决方案2】:

对于在其他情况下发现此问题的每个人。

Android Extensions 的 NPE 也发生在我们为 RecyclerView 编写适配器时(尤其是:编写 CustomViewHolder)。

有关详细信息以及如何解决此问题,请参阅 LayoutContainer

  1. 将此添加到您的模块级 gradle 中
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
        }
}

【讨论】:

  • 这是LayoutContainer 的错误用法。如果您正在使用它,则不应使用View 引用来获取子View(在本例中为containerView.apply)。
  • 我明白了,感谢您的意见。你介意给我一个提示来编辑答案吗?或者您可能想直接编辑我的答案@Eliezer,如果我没记错的话。如果没有containerView.* 访问权限,KTX 将自动导入my_layout.xml 的合成属性,从而给我NPE。而且,我尝试使用LayoutContainer 和使用containerView 来访问子视图。这就是为什么我更喜欢使用来自 google 的数据绑定:youtu.be/Qxj2eBmXLHg?t=505
猜你喜欢
  • 2017-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-07
  • 2020-03-07
  • 1970-01-01
  • 2015-05-22
  • 2022-10-25
相关资源
最近更新 更多