Android 数据绑定:包含标签的可见性

Android Data Binding: visibility on include tag

根据http://developer.android.com/tools/data-binding/guide.html#imports,我们可以在可见性中有这样简单的表达式:

<TextView
..
android:visibility="@{user.isAdult ? View.VISIBLE : View.GONE}"/>

但是当我尝试在 include 标签中做同样的事情时,像这样:

<include
android:id="@+id/image_layout"
layout="@layout/image_layout"
android:visibility="@{notification.notifType == 0 ? View.VISIBLE : View.GONE}"/>

然后 Studio 不仅将表达式显示为红色,而且在构建时会在自动生成的绑定中给出以下错误 class:

Error:(138, 29) error: cannot find symbol method setVisibility(int)

这里是自动生成的绑定出错的地方class

// batch finished
if ((dirtyFlags & 0x3L) != 0) {
    // api target 1
    this.imageLayout.setVisibility(NotifTypeNotificatio1);
}
imageLayout.executePendingBindings();

我想你正在尝试做的事情看起来像这样:

在您要包含的布局中,指定一个布尔变量并将其绑定到所需视图的可见性

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <import type="android.view.View"/>

        <variable
            name="isVisible"
            type="boolean"/>

    </data>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="@{isVisible ? View.VISIBLE : View.GONE}"/>

</layout>

然后在您的调用布局中绑定您的值

<include
    android:id="@+id/image_layout"
    layout="@layout/image_layout"
    bind:isVisible="@{notification.notifType == 0}"/>

您可以通过 "http://schemas.android.com/apk/res-auto" 命名空间将所有必要的参数从父 xml 传递到包含的 xml。

语法是 <res-auto_namespace>:<variable_name> 例如app:isVisible

例如

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

    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <include
            layout="@layout/include_user_image"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:isVisible="@{true}" />

    </android.support.design.widget.CoordinatorLayout>
</layout>

include_user_image.xml

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

    <data>

        <import type="android.view.View" />

        <variable
            name="isVisible"
            type="boolean" />

    </data>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="@{isVisible ? View.VISIBLE : View.GONE}" />
</layout>

这有点晚了,但我最近 运行 通过了这个。

我相信这实际上是数据绑定编译器中的一个错误,因为可以直接在 <include> 标记上设置 android:visibility 属性(即没有数据绑定)。

最佳方式

  1. 可以直接传visibilityInteger值like.
  2. 您也可以通过在绑定中设置 default=gone 来设置 visibility 的默认值。

例如这是included_layout.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="visibility"
            type="int"/>

    </data>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="@{visibility, default=gone}"
        />

</layout>

并使用类似

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

      <import type="android.view.View"/>

    </data>

   <include
     android:id="@+id/included_layout"
     layout="@layout/included_layout"
     app:visibility="@{View.VISIBLE}"/>

</layout>

尝试:

this.imageLayout.getRoot().setVisibility(NotifTypeNotificatio1);

您可以通过其 ID 找到包含的布局,并使用 visibility 属性将其隐藏。

例如在 Kotlin 中,

binding.root.findViewById<CardView>(R.id.layout_inclulded).visibility = View.GONE

其中,

root 是父布局中根元素的默认属性。

在我的案例中,

CardView 是包含的布局的根元素。

R.id.layout_inclulded是被包含的布局在父布局中的id

感谢大家,你们帮了我很多。你的回答是我成功解决这个问题的一部分。

我们想设置图像视图的可见性,这也是某些动画的目标。 Motion Scene 负责管理可见性。设置动议属性app:visibilityMode到"ignore"解决一切

<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<ConstraintSet android:id="@+id/expanded">
<!-- ... -->
    <Constraint
        android:id="@+id/myImageViewId"
        app:visibilityMode="ignore"/>
</ConstraintSet>
<!-- ... -->
</MotionScene>

这是直接方法,无需在包含的布局中传递变量

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include
        layout="@layout/layout_errors"
        android:visibility="@{isVisible ? 0:1 }"
       />

</androidx.constraintlayout.widget.ConstraintLayout>

上面的代码就是我所需要的

有趣的是,如果我把上面的三元运算符去掉,简化成这样,

<include
    layout="@layout/layout_errors"
    android:visibility="@{isVisible}"
   />

使用以下方法添加 BindingAdapter class,

@BindingAdapter("android:visibility")
    public static void setVisibility(View view, boolean isVisible) {
        view.setVisibility(isVisible ? View.VISIBLE : View.GONE);
    } 

轰! OP 错误侵入了我的整个 BuildOutput 跟踪,Android

的有趣世界

更好的方法。

在顶部布局中,声明布尔值或可观察字段,其值可切换所含布局的可见性。然后记得给包含的布局一个 id 否则它不会工作

<?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">
    <data>
        <import type="android.view.View"/>
        <variable
            name="show"
            type="Boolean" />
    </data>
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:background="@color/colorPrimary">


        <include layout="@layout/progress"
            android:id="@+id/progress"
            android:visibility="@{show?View.VISIBLE:View.GONE}"/>

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

我遇到了同样的错误。数据绑定适用于除包含的布局之外的每个视图元素。

不需要解决这个问题,我所做的是用 <layout> 标签包围包含的布局的根,并在其中放置一个折叠的 <data/> 标签 - 初始化包括数据绑定布局。

瞧!成功了。

要在 include 标签中提供可见性,您需要将 included 布局转换为数据绑定,即使在 included 布局上没有传递任何数据。

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

    </data>
    <LinearLayout
        android:id="@+id/myblock"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/main_bg_alternative"
        android:orientation="vertical"
        android:paddingTop="15dp"
        android:paddingBottom="20dp">
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
   <TextView
        android:layout_width="wrap_content"
        android:text="@string/hello"
        android:layout_height="wrap_content"/>
   </LinearLayout>
</layout>

并且在您的 activity XML 上,您可以将可见性用作

<include
     layout="@layout/include_body"
     android:visibility="@{results.size()>0 ? View.VISIBLE : View.GONE, default=gone}"
     tools:visibility="visible" />

不需要数据绑定,而是获取对 <include> 布局的根视图的引用并设置其可见性。例如,

binding.myIncludeLayout.root.visibility = View.VISIBLE