首页 > 解决方案 > Android DataBinding:即使生成也无法访问 LayoutNameDataBinding

问题描述

我的问题是我需要访问我的 LayoutNameBinding,但我无法这样做。只有 DataBinding 生成的可用类是 LayoutNameBindingImpl。

注释部分是我希望能够在我的代码中执行的操作。显示的部分代码灵感来自https://github.com/android/sunflower,它解释了如何使用 Android JetPack 的不同部分。

尝试的解决方案

智能感知结果

大厅片段.kt

package com.kotlin.projet3.ui.lobby

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import com.kotlin.projet3.R
import com.kotlin.projet3.adapters.GAME_LIST_INDEX
import com.kotlin.projet3.adapters.MATCH_HISTORY_INDEX
import com.kotlin.projet3.adapters.PROFILE_INDEX
import com.kotlin.projet3.databinding.LobbyFragmentBindingImpl

class LobbyFragment : Fragment(){
    private lateinit var nav: NavController

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

//        val binding = LobbyFragmentBinding.inflate(inflater,container,false)
//
//        viewPager = binding.viewPager
//        viewPager.adapter = LobbyTabsAdapter(this)
//
//        TabLayoutMediator(binding.tabs, viewPager) { tab, position ->
//            tab.setIcon(getTabIcon(position))
//            tab.text = getTabTitle(position)
//        }.attach()
//
//        return binding.root
        return super.onCreateView(inflater, container, savedInstanceState)
    }

    private fun getTabIcon(position: Int): Int {
        return when (position) {
            GAME_LIST_INDEX -> R.drawable.ic_home_black_24dp
            PROFILE_INDEX -> R.drawable.ic_person_black_24dp
            MATCH_HISTORY_INDEX -> R.drawable.ic_assessment_black_24dp
            else -> throw IndexOutOfBoundsException()
        }
    }

    private fun getTabTitle(position: Int): String? {
        return when (position) {
            GAME_LIST_INDEX -> getString(R.string.home_button)
            PROFILE_INDEX -> getString(R.string.profile_button)
            MATCH_HISTORY_INDEX -> getString(R.string.match_history_button)
            else -> null
        }
    }
}

lobby_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<layout 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">


        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/page_container"
            android:layout_width="0dp"
            android:layout_height="match_parent"


            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toStartOf="parent">

            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                app:layout_constraintBottom_toTopOf="@+id/view_pager"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHeight_percent=".15"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:tabMode="fixed"
                app:tabGravity="fill"
                app:tabIndicatorFullWidth="true" />

            <androidx.viewpager2.widget.ViewPager2
                android:id="@+id/view_pager"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                app:layout_constraintTop_toBottomOf="@+id/tabs"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toEndOf="parent" />

        </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

LobbyFragmentBinding.java(生成的文件)

// Generated by data binding compiler. Do not edit!
package com.kotlin.projet3.databinding;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.tabs.TabLayout;
import com.kotlin.projet3.R;
import java.lang.Deprecated;
import java.lang.Object;

public abstract class LobbyFragmentBinding extends ViewDataBinding {
  @NonNull
  public final ConstraintLayout pageContainer;

  @NonNull
  public final TabLayout tabs;

  @NonNull
  public final ViewPager2 viewPager;

  protected LobbyFragmentBinding(Object _bindingComponent, View _root, int _localFieldCount,
      ConstraintLayout pageContainer, TabLayout tabs, ViewPager2 viewPager) {
    super(_bindingComponent, _root, _localFieldCount);
    this.pageContainer = pageContainer;
    this.tabs = tabs;
    this.viewPager = viewPager;
  }

  @NonNull
  public static LobbyFragmentBinding inflate(@NonNull LayoutInflater inflater,
      @Nullable ViewGroup root, boolean attachToRoot) {
    return inflate(inflater, root, attachToRoot, DataBindingUtil.getDefaultComponent());
  }

  /**
   * This method receives DataBindingComponent instance as type Object instead of
   * type DataBindingComponent to avoid causing too many compilation errors if
   * compilation fails for another reason.
   * https://issuetracker.google.com/issues/116541301
   * @Deprecated Use DataBindingUtil.inflate(inflater, R.layout.lobby_fragment, root, attachToRoot, component)
   */
  @NonNull
  @Deprecated
  public static LobbyFragmentBinding inflate(@NonNull LayoutInflater inflater,
      @Nullable ViewGroup root, boolean attachToRoot, @Nullable Object component) {
    return ViewDataBinding.<LobbyFragmentBinding>inflateInternal(inflater, R.layout.lobby_fragment, root, attachToRoot, component);
  }

  @NonNull
  public static LobbyFragmentBinding inflate(@NonNull LayoutInflater inflater) {
    return inflate(inflater, DataBindingUtil.getDefaultComponent());
  }

  /**
   * This method receives DataBindingComponent instance as type Object instead of
   * type DataBindingComponent to avoid causing too many compilation errors if
   * compilation fails for another reason.
   * https://issuetracker.google.com/issues/116541301
   * @Deprecated Use DataBindingUtil.inflate(inflater, R.layout.lobby_fragment, null, false, component)
   */
  @NonNull
  @Deprecated
  public static LobbyFragmentBinding inflate(@NonNull LayoutInflater inflater,
      @Nullable Object component) {
    return ViewDataBinding.<LobbyFragmentBinding>inflateInternal(inflater, R.layout.lobby_fragment, null, false, component);
  }

  public static LobbyFragmentBinding bind(@NonNull View view) {
    return bind(view, DataBindingUtil.getDefaultComponent());
  }

  /**
   * This method receives DataBindingComponent instance as type Object instead of
   * type DataBindingComponent to avoid causing too many compilation errors if
   * compilation fails for another reason.
   * https://issuetracker.google.com/issues/116541301
   * @Deprecated Use DataBindingUtil.bind(view, component)
   */
  @Deprecated
  public static LobbyFragmentBinding bind(@NonNull View view, @Nullable Object component) {
    return (LobbyFragmentBinding)bind(component, view, R.layout.lobby_fragment);
  }
}

标签: androidandroid-studiokotlindata-bindingandroid-databinding

解决方案


错误跟踪器 https://issuetracker.google.com/issues/151140024

使用的解决方法(可能存在更简单的解决方法,之后进行了查明错误的调查)

  1. 复制 lobby_fragment 和 LobbyFragment 的内容
  2. 删除 lobby_fragment 和 LobbyFragment
  3. 创建 LobbyFragment 和 lobby_fragment
  4. 粘贴复制的内容

经过调查,问题似乎与我的项目中布局文件的排列方式有关。我在 build.gradle(:app) 中定义了额外的资源源目录,当我在执行第一次构建(创建生成的 DataBinding 文件)之前将布局文件移动到这些文件夹时,会出现此线程中的问题。

build.gradle(:app)

android {
    dataBinding {
        enabled = true
    }

    sourceSets {
        main {
            res {
                srcDirs 'src/main/res', 
                'src/main/res/layouts/chat',
                'src/main/res/layouts/authentication', 
                'src/main/res/layouts/lobby'
            }
        }
    }

    ...
}

推荐阅读