使用数据绑定时如何在横向模式下隐藏按钮
How to hide button in landscape mode when using Databinding
我有一个视图使用 DataBinding
显示来自 ViewModel
的数据。当视图处于横向模式时,该视图有一个隐藏的按钮。目前这是通过有两个布局文件来工作的,但我只想有一个,因为重构是一场噩梦。但是如何使用 DataBinding
和 BindingAdapters
来解决这个问题?
如何为给定视图启用以下绑定表达式?
android:visibility="@{isLandscapeMode ? View.INVISIBLE : View.VISIBLE}"
编辑:
我的分机 属性 定义 (ViewUtils.kt
):
val View.isLandscapeMode: Boolean
get() = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
我的布局:
<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"/>
<import type="com.example.base.views.ViewUtilsKt" />
<variable
name="isLandscapeMode "
type="java.lang.Boolean"/>
<variable
name="viewmodel"
type="com.example.ui.task.TaskViewModel" />
</data>
...
<ImageButton
...
android:visibility="@{isLandscapeMode ? View.INVISIBLE : View.VISIBLE}"
...
/>
这会导致编译错误:Cause: not a valid name: isLandscapeMode
您必须检查您的绑定适配器当前处于哪个 phone 方向。这是另一个 post,您可以在其中找到问题的答案 how to detect orientation of android device?
编辑:
您需要检测方向并将其保存为布尔值。稍后你必须将该变量传递给你的适配器,在这种情况下它将是布尔值。
<data>
<import type="android.view.View"/>
<variable
name="isLandscapeMode"
type="boolean"/>
</data>
对于需要相同行为的其他人。有两种解决方法。
第一个解决方案(创建一个BindingAdapter
并在您选择的UI元素上使用它):
@BindingAdapter("bind:visibleInLandscapeMode")
fun View.setVisibleInLandscapeMode(visible: Boolean) {
Timber.d("setVisibleInLandscapeMode() returns ${resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE}")
visibility = if (visible && (resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE)) VISIBLE else INVISIBLE
}
在您的 XML 布局中:
<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"
xmlns:bind="http://schemas.android.com/apk/lib/com.example">
...
<ImageButton
...
bind:visibleInLandscapeMode="false"
...
/>
第二种解决方案(创建一个改变UI元素可见性的绑定表达式):
<ImageButton
...
android:visibility="@{context.getResources.getConfiguration.orientation == Configuration.ORIENTATION_LANDSCAPE ? View.INVISIBLE : View.VISIBLE}"
...
/>
记住正确的导入:
<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"/>
<import type="android.content.res.Resources" />
<import type="android.content.res.Configuration" />
...
</data>
...
顺便说一句。在 AndroidAnnotation. See issue here and here.
中使用数据绑定时要小心
我有一个视图使用 DataBinding
显示来自 ViewModel
的数据。当视图处于横向模式时,该视图有一个隐藏的按钮。目前这是通过有两个布局文件来工作的,但我只想有一个,因为重构是一场噩梦。但是如何使用 DataBinding
和 BindingAdapters
来解决这个问题?
如何为给定视图启用以下绑定表达式?
android:visibility="@{isLandscapeMode ? View.INVISIBLE : View.VISIBLE}"
编辑:
我的分机 属性 定义 (ViewUtils.kt
):
val View.isLandscapeMode: Boolean
get() = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
我的布局:
<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"/>
<import type="com.example.base.views.ViewUtilsKt" />
<variable
name="isLandscapeMode "
type="java.lang.Boolean"/>
<variable
name="viewmodel"
type="com.example.ui.task.TaskViewModel" />
</data>
...
<ImageButton
...
android:visibility="@{isLandscapeMode ? View.INVISIBLE : View.VISIBLE}"
...
/>
这会导致编译错误:Cause: not a valid name: isLandscapeMode
您必须检查您的绑定适配器当前处于哪个 phone 方向。这是另一个 post,您可以在其中找到问题的答案 how to detect orientation of android device?
编辑:
您需要检测方向并将其保存为布尔值。稍后你必须将该变量传递给你的适配器,在这种情况下它将是布尔值。
<data>
<import type="android.view.View"/>
<variable
name="isLandscapeMode"
type="boolean"/>
</data>
对于需要相同行为的其他人。有两种解决方法。
第一个解决方案(创建一个BindingAdapter
并在您选择的UI元素上使用它):
@BindingAdapter("bind:visibleInLandscapeMode")
fun View.setVisibleInLandscapeMode(visible: Boolean) {
Timber.d("setVisibleInLandscapeMode() returns ${resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE}")
visibility = if (visible && (resources.configuration.orientation != Configuration.ORIENTATION_LANDSCAPE)) VISIBLE else INVISIBLE
}
在您的 XML 布局中:
<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"
xmlns:bind="http://schemas.android.com/apk/lib/com.example">
...
<ImageButton
...
bind:visibleInLandscapeMode="false"
...
/>
第二种解决方案(创建一个改变UI元素可见性的绑定表达式):
<ImageButton
...
android:visibility="@{context.getResources.getConfiguration.orientation == Configuration.ORIENTATION_LANDSCAPE ? View.INVISIBLE : View.VISIBLE}"
...
/>
记住正确的导入:
<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"/>
<import type="android.content.res.Resources" />
<import type="android.content.res.Configuration" />
...
</data>
...
顺便说一句。在 AndroidAnnotation. See issue here and here.
中使用数据绑定时要小心