簡體   English   中英

缺少帶有視圖綁定和導航組件的 ID 的必需視圖

[英]Missing required view with ID with view binding and navigation component

我正在嘗試將我的項目遷移到視圖綁定,當我啟動我的應用程序時出現異常。

我的主要活動包含一個 NavHostFragment,如下所示:

<?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:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        android:orientation="vertical">

    ...

    <androidx.fragment.app.FragmentContainerView
            android:id="@+id/nav_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            app:defaultNavHost="true"
            app:navGraph="@navigation/nav_graph" />

    ...

</LinearLayout>

NavHostFragment 中默認加載的第一個片段是這樣實現的:

class ToolListFragment : Fragment(R.layout.fragment_tool_list) {
    ...
    private var _binding: FragmentToolListBinding? = null
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentToolListBinding.inflate(layoutInflater, container, false)
        return binding.root
    }
    ...
}

這是片段布局的相關部分:

<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"
        tools:context=".ToolListFragment"
        android:orientation="vertical"
        android:background="@android:color/white">

    <com.google.android.material.tabs.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:tabMode="fixed"
            app:tabGravity="fill">
        <com.google.android.material.tabs.TabItem
                android:id="@+id/tab_around_me"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:text="@string/tool_filter_around_me"/>
        <com.google.android.material.tabs.TabItem
                android:id="@+id/tab_assigned_to_me"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:text="@string/tool_filter_assigned_to_me"/>
        <com.google.android.material.tabs.TabItem
                android:id="@+id/tab_all_tools"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:text="All"/>
    </com.google.android.material.tabs.TabLayout>
    ...
</LinearLayout>

如您所見,有一個 ID 為 tab_all 的 TabItem。 然而,這是使我的應用程序崩潰的異常:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.herontrack.dev, PID: 12477
java.lang.NullPointerException: Missing required view with ID: com.herontrack.dev:id/tab_all_tools
    at com.herontrack.databinding.FragmentToolListBinding.bind(FragmentToolListBinding.java:133)
    at com.herontrack.databinding.FragmentToolListBinding.inflate(FragmentToolListBinding.java:78)
    at com.herontrack.ToolListFragment.onCreateView(ToolListFragment.kt:107)
    at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2950)
    at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:515)
    at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
    at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1636)
    at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3112)
    at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:3049)
    at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2975)
    at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:543)
    at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
    at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1636)
    at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3112)
    at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:3056)
    at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:251)
    at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:473)
    at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:210)
    at com.herontrack.MainActivity.onStart(MainActivity.kt:100)
    at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1435)
    at android.app.Activity.performStart(Activity.java:8024)
    at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3475)
    at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
    at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
    at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:223)
    at android.app.ActivityThread.main(ActivityThread.java:7656)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

所以它在ToolListFragment.onCreateView()的這一行崩潰

_binding = FragmentToolListBinding.inflate(layoutInflater, container, false)

但我真的不明白為什么。

您面臨的問題是TabItem只是一個虛擬視圖。 查看源代碼可以看到

/**
 * TabItem is a special 'view' which allows you to declare tab items for a {@link TabLayout} within
 * a layout. This view is not actually added to TabLayout, it is just a dummy which allows setting
 * of a tab items's text, icon and custom layout. See TabLayout for more information on how to use
 * it.
 *
 * @attr ref com.google.android.material.R.styleable#TabItem_android_icon
 * @attr ref com.google.android.material.R.styleable#TabItem_android_text
 * @attr ref com.google.android.material.R.styleable#TabItem_android_layout
 * @see TabLayout
 */
//TODO(b/76413401): make class final after the widget migration
public class TabItem extends View {

因此 ViewBinding 找不到具有您指定的 ID 的Tab ,因為它沒有添加到視圖層次結構中。 要解決此問題,您必須從TabItem中刪除id 如果您需要訪問Tab ,您可以使用以下代碼。

// to access first tab
binding.tabs.getTabAt(0)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM