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
属性(即没有数据绑定)。
最佳方式
- 可以直接传
visibility
的Integer
值like.
- 您也可以通过在绑定中设置
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
根据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
属性(即没有数据绑定)。
最佳方式
- 可以直接传
visibility
的Integer
值like. - 您也可以通过在绑定中设置
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