在使用视图绑定时,如何处理不同布局配置中缺少的视图?

我知道任何带有ID的XML元素都应该通过视图绑定自动拉入到活动类中。然而,Android Studio一直建议我的按钮是可空的,需要有?.!!.才能编译。

如果我用!!.断言不可为空,则实际上会导致该按钮的运行时出现NullPointerException异常。

为什么视图绑定无法识别我的按钮的类型和存在?

我的主要活动代码如下:

package com.stevenswang.ageinminutes

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.stevenswang.ageinminutes.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.btnSelectDate.setOnClickListener {...} //this line gives the compiler error in the title
    }
    
}

应用程序的XML在此处(完整):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:background="@color/backgroundColor"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    android:padding="16sp"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="Caculate Your"
        android:textColor="@color/headingColor"
        android:textSize="30sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/tvAge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:text="Age"
        android:textColor="@color/white"
        android:background="@color/purple_200"
        android:padding="10sp"
        android:textSize="30sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/tvInMinutes"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:text="In Minutes"
        android:textColor="@color/headingColor"
        android:textSize="30sp"
        android:textStyle="bold" />

    <Button
        android:id="@+id/btnSelectDate"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Select Date"
        android:layout_marginTop="10sp"
        android:textSize="20sp"
        android:backgroundTint="@color/buttonColor"
        />

    <TextView
        android:id="@+id/tvSelectedDate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:textColor="@color/headingColor"
        android:textSize="20sp"
        />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Selected Date"
        android:layout_marginTop="2dp"
        android:textColor="@color/gray"
        android:textSize="20sp"
        />

    <TextView
        android:id="@+id/tvAgeInMinutes"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:textColor="@color/headingColor"
        android:textSize="36sp"
        android:textStyle="bold"
        />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Age in minutes"
        android:layout_marginTop="2dp"
        android:textColor="@color/gray"
        android:textSize="24sp"
        />


</LinearLayout>

我找到了罪魁祸首,在视图绑定文档上写着:

空安全性:由于视图绑定创建对视图的直接引用,因此不存在由于无效的视图ID而导致空指针异常的风险。此外,当视图仅出现在布局的某些配置中时,绑定类中包含其引用的字段将标记为@Nullable

来源:https://developer.android.com/topic/libraries/view-binding#findviewbyid

我的按钮中有一个规则只在API 21或更高版本中使用,我当前的最小设置为16(见下面的截图)。我按照Android Studio的建议覆盖了版本,从而创建了两个独立的activity_main.xml。这就是触发可空行为的原因。

当我删除v21 XML文件时,可为空的项消失了。

现在,在我对阅读这篇文章的人的后续问题中,为什么断言不可为空仍然会导致应用程序崩溃?处理多个activity_main.xml版本的正确方法是什么?

提前谢谢!


解决方案

我找到了罪魁祸首,在视图绑定文档上写着:

空安全性:由于视图绑定创建对视图的直接引用,因此不存在由于无效的视图ID而导致空指针异常的风险。此外,当视图仅出现在布局的某些配置中时,绑定类中包含其引用的字段将标记为@Nullable

来源:https://developer.android.com/topic/libraries/view-binding#findviewbyid

我的按钮中有一个规则只在API 21或更高版本中使用,我当前的最小设置为16(见下面的截图)。我按照Android Studio的建议覆盖了版本,从而创建了两个独立的activity_main.xml。这就是触发可空行为的原因。

当我删除v21 XML文件时,可为空的项消失了。

现在,在我对阅读这篇文章的人的后续问题中,为什么断言不可为空仍然会导致应用程序崩溃?处理多个activity_main.xml版本的正确方法是什么?

相关文章