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

时间:2016-03-01 13:08:24

标签: android android-databinding

根据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不仅以红色显示表达式,而且在构建时它会在自动生成的绑定类中显示以下错误:

  

错误:(138,29)错误:找不到符号方法setVisibility(int)

这是自动生成的绑定类

中发生错误的位置
// batch finished
if ((dirtyFlags & 0x3L) != 0) {
    // api target 1
    this.imageLayout.setVisibility(NotifTypeNotificatio1);
}
imageLayout.executePendingBindings();

12 个答案:

答案 0 :(得分:55)

我想你要做的事情会是这样的:

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

<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}"/>

答案 1 :(得分:5)

更好的方法。

在顶部布局上,声明布尔值或可观察字段,其值将切换所包含布局的可见性。然后请记住给包含的布局一个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>

答案 2 :(得分:2)

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

语法为res-auto namespace:variable name

例如

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

答案 3 :(得分:2)

这有点晚了,但是我最近遇到了这个问题。

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

答案 4 :(得分:2)

尝试:

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

答案 5 :(得分:1)

最佳方式

  1. 您可以像这样直接传递Integer的{​​{1}}值。
  2. 您还可以通过在绑定中设置visibility来设置visibility的默认值。

例如,这是default=gone

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>

答案 6 :(得分:1)

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

没有必要对此有解决方法,我所做的是我用 <layout> 标签包围了包含布局的根,并在其中放置了一个折叠的 <data/> 标签 - 初始化了包含的布局用于数据绑定。

瞧!成功了。

答案 7 :(得分:1)

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

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

在您的活动 XML 上,您可以将可见性用作

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

答案 8 :(得分:0)

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

例如在科特林,

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

其中

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

在我的案例中,

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

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

答案 9 :(得分:0)

谢谢大家,您对我有很大帮助。您的回答是我成功解决此问题的一部分。

我们想要设置图像视图的可见性,这也是某些动画的目标。运动场景负责可视性的管理。将运动属性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>

答案 10 :(得分:0)

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

<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类

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

景气! OP错误入侵了我的整个BuildOutput跟踪,这是 Android

的有趣世界

答案 11 :(得分:0)

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

binding.myIncludeLayout.root.visibility = View.VISIBLE

相关问题