使用 Observable 布尔值设置 android 视图的可见性
Using Observable Boolean to set visibility of an android view
这是关于我在代码审查中一直争论不休的一些非常微不足道的事情。情景是这样的。有一个数据绑定布局:some_layout.xml
,由 ViewModel
.
支持
[some_layout.xml
的内容]
<?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="viewModel" type="some.long.package.name.SomeViewModel"/>
</data>
<!-- Other stuffs -->
<TextView
<!-- Other parameters-->>
android:visibility="@{viewModel.someObservableBool?View.VISIBLE : View.GONE}"
/>
</layout>
要求,当布尔值是 false
时,我希望 TextView
是 View.GONE
(而不是 View.INVISIBLE
)。我的代码的审阅者坚持这个事实,我应该直接使用布尔值而不是三元运算符 android:visibility
[android:visibility="@{viewModel.someObservableBool}"
]
现在我的理解是因为真值隐式转换为int会导致视图是Visible
/Invisible
而不是Gone
。正如 attrs.xml
定义所述,
<!-- Controls the initial visibility of the view. -->
<attr name="visibility">
<!-- Visible on screen; the default value. -->
<enum name="visible" value="0" />
<!-- Not displayed, but taken into account during layout (space is left for it). -->
<enum name="invisible" value="1" />
<!-- Completely hidden, as if the view had not been added. -->
<enum name="gone" value="2" />
</attr>
我的理解有误吗?
java 中没有隐式类型转换,整数值不会被解释为布尔值 - 这意味着如果你写
<TextView
<!-- Other parameters-->>
android:visibility="@{viewModel.someObservableBool}"
/>
它只是不会编译。
但是如果你加上
@BindingConversion
fun booleanToVisibility(value: Boolean?) = if (value == true)View.VISIBLE else View.GONE
应该可以。您可以查看相关文档here
我正在以这种方式使用它进行电子邮件验证,ObservableBoolean:
XML:
<data>
<import type="android.view.View" />
<variable
name="isProperEmail"
type="androidx.databinding.ObservableBoolean" />
</data>
<!-- your other code here-->
<androidx.appcompat.widget.AppCompatImageView
---------
---------
android:visibility="@{isProperEmail ?View.VISIBLE : View.GONE}" />
并在 class 中使用它:
private val isProperEmail = ObservableBoolean(false)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
-------------
binding.isProperEmail = isProperEmail
}
现在,每当您更改此 class' isProperEmail
变量的值时,它都会更改并影响到 XML/Layout.
如果在 XML
中导入 viewModel
和 View
实例,我会采用以下方法
<TextView
android:visibility="@{(viewModel.someObservableBool())? View.VISIBLE : View.GONE}" />
无需导入 Observable 变量,因为 viewModel 在此上下文中已经可用。
这是关于我在代码审查中一直争论不休的一些非常微不足道的事情。情景是这样的。有一个数据绑定布局:some_layout.xml
,由 ViewModel
.
[some_layout.xml
的内容]
<?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="viewModel" type="some.long.package.name.SomeViewModel"/>
</data>
<!-- Other stuffs -->
<TextView
<!-- Other parameters-->>
android:visibility="@{viewModel.someObservableBool?View.VISIBLE : View.GONE}"
/>
</layout>
要求,当布尔值是 false
时,我希望 TextView
是 View.GONE
(而不是 View.INVISIBLE
)。我的代码的审阅者坚持这个事实,我应该直接使用布尔值而不是三元运算符 android:visibility
[android:visibility="@{viewModel.someObservableBool}"
]
现在我的理解是因为真值隐式转换为int会导致视图是Visible
/Invisible
而不是Gone
。正如 attrs.xml
定义所述,
<!-- Controls the initial visibility of the view. -->
<attr name="visibility">
<!-- Visible on screen; the default value. -->
<enum name="visible" value="0" />
<!-- Not displayed, but taken into account during layout (space is left for it). -->
<enum name="invisible" value="1" />
<!-- Completely hidden, as if the view had not been added. -->
<enum name="gone" value="2" />
</attr>
我的理解有误吗?
java 中没有隐式类型转换,整数值不会被解释为布尔值 - 这意味着如果你写
<TextView
<!-- Other parameters-->>
android:visibility="@{viewModel.someObservableBool}"
/>
它只是不会编译。
但是如果你加上
@BindingConversion
fun booleanToVisibility(value: Boolean?) = if (value == true)View.VISIBLE else View.GONE
应该可以。您可以查看相关文档here
我正在以这种方式使用它进行电子邮件验证,ObservableBoolean:
XML:
<data>
<import type="android.view.View" />
<variable
name="isProperEmail"
type="androidx.databinding.ObservableBoolean" />
</data>
<!-- your other code here-->
<androidx.appcompat.widget.AppCompatImageView
---------
---------
android:visibility="@{isProperEmail ?View.VISIBLE : View.GONE}" />
并在 class 中使用它:
private val isProperEmail = ObservableBoolean(false)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
-------------
binding.isProperEmail = isProperEmail
}
现在,每当您更改此 class' isProperEmail
变量的值时,它都会更改并影响到 XML/Layout.
如果在 XML
中导入viewModel
和 View
实例,我会采用以下方法
<TextView
android:visibility="@{(viewModel.someObservableBool())? View.VISIBLE : View.GONE}" />
无需导入 Observable 变量,因为 viewModel 在此上下文中已经可用。