自定义景观布局膨胀时数据绑定失败

her*_*lon 3 xml android android-layout kotlin

我创建了一个用于横向的替代布局 XML 文件。使用 的膨胀DataBindingUtil在纵向模式下工作正常,但在加载自定义 XML 文件时在横向模式下崩溃。

使用 DataBinding 进行布局膨胀:

class AskhostingFragment : Fragment() {

    private lateinit var binding : FragmentAskhostingBinding

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_askhosting, container, false)

        return binding.root
    }
}
Run Code Online (Sandbox Code Playgroud)

我包含了这两个 XML 文件,尽管我怀疑它们与该问题相关。布局/fragment_askhosting.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/askhosting_cl_root"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/askhosting_cl_1"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:background="@color/colorPrimaryDark"
            app:layout_constraintBottom_toTopOf="@+id/askhosting_cl_2"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <TextView
                android:id="@+id/textView3"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="64dp"
                android:layout_marginTop="64dp"
                android:layout_marginEnd="64dp"
                android:text="@string/askhosting_option_stundenplan24"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                style="@style/TextLargeMultiline" />

            <Button
                android:id="@+id/button3"
                style="@style/Widget.AppCompat.Button.Colored"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:layout_marginEnd="32dp"
                android:layout_marginBottom="32dp"
                android:text="@string/stundenplan24"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/textView3"
                app:layout_constraintVertical_bias="1.0" />
        </androidx.constraintlayout.widget.ConstraintLayout>

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/askhosting_cl_2"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:background="@color/colorPrimary"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/askhosting_cl_1">

            <ImageView
                android:id="@+id/imageView2"
                android:layout_width="110dp"
                android:layout_height="110dp"
                android:layout_marginTop="32dp"
                android:layout_marginEnd="32dp"
                android:contentDescription="@string/school_website"
                android:tint="@color/colorPrimaryDark"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:srcCompat="@drawable/ic_web_black" />

            <TextView
                android:id="@+id/textView4"
                style="@style/TextLargeMultiline"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="64dp"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="64dp"
                android:text="@string/askhosting_option_website"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.0"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/imageView2" />

            <Button
                android:id="@+id/button4"
                style="@style/Widget.AppCompat.Button.Colored"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:layout_marginEnd="32dp"
                android:layout_marginBottom="32dp"
                android:text="@string/school_website"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/textView4"
                app:layout_constraintVertical_bias="1.0" />
        </androidx.constraintlayout.widget.ConstraintLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)

布局土地/fragment_askhosting.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/askhosting_cl_root"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/askhosting_cl_1"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:background="@color/colorPrimaryDark"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/askhosting_cl_2"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <TextView
                android:id="@+id/textView3"
                style="@style/TextLargeMultiline"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="64dp"
                android:layout_marginTop="64dp"
                android:layout_marginEnd="64dp"
                android:text="@string/askhosting_option_stundenplan24"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <Button
                android:id="@+id/button3"
                style="@style/Widget.AppCompat.Button.Colored"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:layout_marginEnd="32dp"
                android:layout_marginBottom="32dp"
                android:text="@string/stundenplan24"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/textView3"
                app:layout_constraintVertical_bias="1.0" />
        </androidx.constraintlayout.widget.ConstraintLayout>

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/askhosting_cl_2"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:background="@color/colorPrimary"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@+id/askhosting_cl_1"
            app:layout_constraintTop_toTopOf="parent">

            <ImageView
                android:id="@+id/imageView2"
                android:layout_width="110dp"
                android:layout_height="110dp"
                android:layout_marginTop="32dp"
                android:layout_marginEnd="32dp"
                android:contentDescription="@string/school_website"
                android:tint="@color/colorPrimaryDark"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:srcCompat="@drawable/ic_web_black" />

            <TextView
                android:id="@+id/textView4"
                style="@style/TextLargeMultiline"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="64dp"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="64dp"
                android:text="@string/askhosting_option_website"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.0"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/imageView2" />

            <Button
                android:id="@+id/button4"
                style="@style/Widget.AppCompat.Button.Colored"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="8dp"
                android:layout_marginEnd="32dp"
                android:layout_marginBottom="32dp"
                android:text="@string/school_website"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/textView4"
                app:layout_constraintVertical_bias="1.0" />
        </androidx.constraintlayout.widget.ConstraintLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)

将设备转为横向模式(或横向启动应用程序)时出现错误消息:

java.lang.IllegalArgumentException: The tag for fragment_askhosting is invalid. Received: layout-land/fragment_askhosting_0
        at net.hermlon.gcgtimetable.DataBinderMapperImpl.getDataBinder(DataBinderMapperImpl.java:42)
        at androidx.databinding.MergedDataBinderMapper.getDataBinder(MergedDataBinderMapper.java:74)
        at androidx.databinding.DataBindingUtil.bind(DataBindingUtil.java:199)
        at androidx.databinding.DataBindingUtil.inflate(DataBindingUtil.java:130)
        at androidx.databinding.DataBindingUtil.inflate(DataBindingUtil.java:95)
        at net.hermlon.gcgtimetable.ui.profile.create.AskhostingFragment.onCreateView(AskhostingFragment.kt:21)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
        at androidx.fragment.app.FragmentManagerImpl.addAddedFragments(FragmentManagerImpl.java:2100)
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1874)
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1830)
        at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2663)
        at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2613)
        at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2624)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:904)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2659)
        at androidx.fragment.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2613)
        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:246)
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:542)
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:201)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1425)
        at android.app.Activity.performStart(Activity.java:7825)
        at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3294)
        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:2016)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Run Code Online (Sandbox Code Playgroud)

引发异常的代码是生成文件中的以下函数app/build/generated/source/kapt/debug/net/hermlon/gcgtimetable/DataBinderMapperImpl.java

@Override
  public ViewDataBinding getDataBinder(DataBindingComponent component, View view, int layoutId) {
    int localizedLayoutId = INTERNAL_LAYOUT_ID_LOOKUP.get(layoutId);
    if(localizedLayoutId > 0) {
      final Object tag = view.getTag();
      if(tag == null) {
        throw new RuntimeException("view must have a tag");
      }
      switch(localizedLayoutId) {
        case  LAYOUT_FRAGMENTASKHOSTING: {
          if ("layout/fragment_askhosting_0".equals(tag)) {
            return new FragmentAskhostingBindingImpl(component, view);
          }
          throw new IllegalArgumentException("The tag for fragment_askhosting is invalid. Received: " + tag);
        }
      }
    }
    return null;
  }
Run Code Online (Sandbox Code Playgroud)

我猜当 DataBinding 所获得的布局的标签(无论这是什么)由于横向布局的膨胀而发生更改时,就会出现问题。这是一个错误还是 DataBinding 无法处理两个可更改的布局文件?

更新:似乎这将是一段时间以来的已知问题:https ://issuetracker.google.com/issues/62740925 对于某些人来说,多个布局似乎工作正常:具有多个布局的Android数据绑定

her*_*lon 7

已解决:数据绑定与横向布局完美配合,我只需重建应用程序(构建->重建项目)。现在生成的代码如下所示,并且不再抛出异常:

@Override
  public ViewDataBinding getDataBinder(DataBindingComponent component, View view, int layoutId) {
    int localizedLayoutId = INTERNAL_LAYOUT_ID_LOOKUP.get(layoutId);
    if(localizedLayoutId > 0) {
      final Object tag = view.getTag();
      if(tag == null) {
        throw new RuntimeException("view must have a tag");
      }
      switch(localizedLayoutId) {
        case  LAYOUT_FRAGMENTASKHOSTING: {
          if ("layout/fragment_askhosting_0".equals(tag)) {
            return new FragmentAskhostingBindingImpl(component, view);
          }
          if ("layout-land/fragment_askhosting_0".equals(tag)) {
            return new FragmentAskhostingBindingLandImpl(component, view);
          }
          throw new IllegalArgumentException("The tag for fragment_askhosting is invalid. Received: " + tag);
        }
      }
    }
    return null;
  }
Run Code Online (Sandbox Code Playgroud)