简体   繁体   中英

View must have a tag error in android data binding

I've two layouts for a screen. Activity works fine while setting a layout for Mobile device but it's causing error while setting layout for tablet device. The main issue is:

Caused by: java.lang.RuntimeException: view must have a tag at com.mypackage.DataBinderMapperImpl.getDataBinder(DataBinderMapperImpl.java:941)

Though, I don't face the problem when I install app on mobile device.

This way I'm setting layout on activity:

val resetPasswordActivityBinding = DataBindingUtil.setContentView<ResetPasswordActivityBinding>(this,
                R.layout.reset_password_activity)
resetPasswordActivityBinding.resetPasswordViewModel = resetPasswordViewModel

Here is my XML layout for tablet screen:

<?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">

    <data>

        <variable
            name="resetPasswordViewModel"
            type="com.bhi.salesarchitect.user.password.reset.ResetPasswordViewModel" />

    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <include
            android:id="@+id/toolbar"
            layout="@layout/app_toolbar_layout"
            app:appTheme="@{resetPasswordViewModel.appTheme}"
            app:appToolbar="@{resetPasswordViewModel.appToolbar}" />

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/bg_splash"
                android:contentDescription="@null"
                android:scaleType="centerCrop" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="horizontal">

                <ImageView
                    android:id="@+id/imv_builder_logo_change_pswd"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/dp_135"
                    android:layout_marginBottom="@dimen/space_xxlarge"
                    android:layout_weight=".5"
                    android:contentDescription="@null"
                    android:src="@drawable/ic_logo" />

                <FrameLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_marginEnd="@dimen/dp_80"
                    android:layout_weight=".4">

                    <ImageView
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:layout_marginStart="@dimen/space_normal"
                        android:layout_marginEnd="@dimen/space_normal"
                        android:contentDescription="@null"
                        android:scaleType="fitXY"
                        android:src="@drawable/bg_white_shadow" />

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:orientation="vertical"
                        android:paddingStart="@dimen/space_xxxlarge"
                        android:paddingEnd="@dimen/space_xxxlarge">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_marginTop="@dimen/dp_55"
                            android:layout_marginBottom="@dimen/space_small"
                            android:gravity="center"
                            android:text="@string/a_one_time_password_reset_code_has_been_sent_to_your_email"
                            android:textColor="@color/blue_dark_main"
                            android:textSize="@dimen/text_size_normal" />

                        <EditText
                            android:id="@+id/et_otp"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:layout_marginTop="@dimen/space_normal"
                            android:background="@drawable/shape_rounded_white"
                            android:drawablePadding="@dimen/space_small"
                            android:hint="@string/password_reset_code"
                            android:inputType="textPersonName"
                            android:paddingStart="@dimen/space_small"
                            android:paddingTop="@dimen/space_xsmall"
                            android:paddingEnd="@dimen/space_xxsmall"
                            android:paddingBottom="@dimen/space_xsmall"
                            android:textColor="@android:color/black"
                            android:textSize="@dimen/sp_15" />

                        <EditText
                            android:id="@+id/et_password"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:layout_marginTop="@dimen/space_small"
                            android:background="@drawable/shape_rounded_white"
                            android:drawableStart="@drawable/ic_password"
                            android:drawablePadding="@dimen/space_small"
                            android:hint="@string/new_password"
                            android:inputType="textPassword"
                            android:maxLength="@integer/max_password_length"
                            android:paddingStart="@dimen/space_small"
                            android:paddingTop="@dimen/space_xsmall"
                            android:paddingEnd="@dimen/space_xxsmall"
                            android:paddingBottom="@dimen/space_xsmall"
                            android:textColor="@android:color/black"
                            android:textSize="@dimen/sp_15" />

                        <EditText
                            android:id="@+id/et_confirm_password"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:layout_marginTop="@dimen/space_small"
                            android:background="@drawable/shape_rounded_white"
                            android:drawableStart="@drawable/ic_password"
                            android:drawablePadding="@dimen/space_small"
                            android:hint="@string/confirm_new_password"
                            android:imeOptions="actionDone"
                            android:inputType="textPassword"
                            android:maxLength="@integer/max_password_length"
                            android:paddingStart="@dimen/space_small"
                            android:paddingTop="@dimen/space_xsmall"
                            android:paddingEnd="@dimen/space_xxsmall"
                            android:paddingBottom="@dimen/space_xsmall"
                            android:textColor="@android:color/black"
                            android:textSize="@dimen/sp_15" />

                        <Button
                            android:id="@+id/bt_submit"
                            style="@style/ButtonNormal"
                            android:layout_marginTop="@dimen/space_normal"
                            android:backgroundTint="@color/blue_dark_main"
                            android:onClick="@{()-> resetPasswordViewModel.onSubmitClick()}"
                            android:text="@string/submit"
                            android:textColor="@android:color/white" />

                    </LinearLayout>

                </FrameLayout>

            </LinearLayout>

        </FrameLayout>
    </LinearLayout>
</layout>

I ran into this when I had:

  • A library module defining a layout resource
  • An app module that depended upon that library module defining the same layout resource
  • The library layout resource was set up for data binding (eg, root <layout> element), but the app module's edition of that layout resource was not

In my case, the app module's layout was left over from when I created the project. Removing it cleared up the problem.

Keeping two layouts, one with layout tag of data-binding and another without it, is the common cause of this issue.

I got stuck when I renamed my two normal layout files with same name (/layout and /layout-sw720dp) and used tag. Then, it worked for mobile device but not for tablet. So, after cleaning project, it all started working.

I was having this problem when using an array adapter, having a crash due to a missing tag on convertView. In my getView(), I was doing:

override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
    if (convertView == null) {
        DataBindingUtil.inflate<ItemSpinnerDropDownWorkPackageFilterBinding>(
            LayoutInflater.from(parent.context),
            R.layout.item_spinner_drop_down_work_package_filter,
            parent,
            false
        )
    } else {
        binding = ItemSpinnerDropDownWorkPackageFilterBinding.bind(convertView) 
        binding.text1.setText(getItem(position))
        setDividerVisibility(binding.divider, position)
        return convertView
    }    

}

Which was crashing. The solution was to set the tag on the first run through getView:

 override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
    val binding = if (convertView == null) {
        DataBindingUtil.inflate<ItemSpinnerDropDownWorkPackageFilterBinding>(
            LayoutInflater.from(parent.context),
            R.layout.item_spinner_drop_down_work_package_filter,
            parent,
            false
        )
    } else {
        convertView.tag as ItemSpinnerDropDownWorkPackageFilterBinding
    }
    binding.text1.setText(getItem(position))
    setDividerVisibility(binding.divider, position)
    binding.root.tag = binding
    return binding.root

}

您需要在 app_toolbar_layout 布局文件的开头添加布局标签

You must have <layout> tag into your all XML views (portrait, landscape, tablet, etc.). Even you have to include <layout> tag into included views (" @layout/app_toolbar_layout ").

i was facing similar error so my work around was

DataBindingUtil.bind(holder.itemView)?.apply { item = items[position] }

我只需要在删除资源文件后清理和重建。

可能是您有多个 xml 布局文件。

如果您已经在 xml 文件中使用了布局标记,但仍然出现错误,只需重命名布局文件名并再次清理/重建项目即可修复

Using viewStub with databinding:

class MyFragment {
    lateinit var binding: MyFragmentBinding
    lateinit var viewStubBinding: MyViewStubBinding
    
    private fun setViewStub() {
        binding.myViewStub.setOnInflateListener { viewStub, view ->
            viewStubBinding = binding.myViewStub.binding as MyViewStubBinding // property viewStubBinding is finally inflated
        }
        binding.myViewStub.viewStub?.inflate() // inflate viewStub with defined layout file in XML
    }
}

When I tried to use MyViewStubBinding.bind(view / viewStub) it crash on View must have a tag . This happen because ViewStubProxy try to inflate binding class by itself, so when I try to call bind() by myself on same Binding class, it was already bound and crashed with this error.

I had this error trying to bind separately as my view is inflated within a library but I supply the layout.

The doc says you can do this:

val binding: MyLayoutBinding = MyLayoutBinding.bind(viewRoot)

The viewRoot I was passing was derived from the custom class but ended up being a parent of my layout file (the one that included the layout tag). So I had to specify the view as the root of my layout file via findViewById

除了这个答案,你还需要这个

I encounter this problem, the root case is there are duplicate layout resource file in different module. delete the redundant one to resolve the issue.

In my case worked this code to set content view with data binding.

binding = GenericItemDetailsListBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM