过去几周我一直在使用数据绑定库,考虑到它是第一个版本,它的强大功能令人惊讶。
到目前为止,我发现的唯一错误有一个解决方法。我会在下面解释。
在数据绑定布局文件(现在使用<layout> 标记作为根的布局文件)中使用<include> 标记时,生成的代码会为<include> 标记的父视图组创建一个绑定。
当使用 DataBindingUtil 扩展视图时,应用程序将在尝试解析 ViewGroup 时崩溃。代码生成器和运行时绑定逻辑之间似乎存在不同的行为。
问题示例
这是一个存在上述问题的示例布局。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
</data>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- This include causes no issues -->
<include
layout="@layout/view_content"/>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- This include however causes the data binding to crash on the ScrollView -->
<include
layout="@layout/view_content"/>
</ScrollView>
</RelativeLayout>
</layout>
这是包含的布局。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
</data>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Test"/>
</layout>
当尝试使用 DataBindingUtil.setContentView 时会发生以下崩溃。
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ScrollView.setTag(java.lang.Object)' on a null object reference
解决方案(解决方法)
我发现的临时解决方法是将虚拟值绑定到<include> 标记的父视图组。这允许数据绑定器在运行时找到 ViewGroup,避免崩溃。
以下是实际修复的示例:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="com.example.ViewModel"/>
</data>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- This include causes no issues -->
<include
layout="@layout/view_content"/>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
bind:visibility="@{viewModel.dummyVisibility}">
<!-- This include will not cause a problem now that the ScrollView has a value being bound -->
<include
layout="@layout/view_content"/>
</ScrollView>
</RelativeLayout>
</layout>
这是最基本的视图模型:
package com.example;
import android.databinding.BaseObservable;
import android.databinding.Bindable;
import android.view.View;
public class ViewModel extends BaseObservable {
@Bindable
public int getDummyVisibility() {
// TODO: This is a work around. Currently data binding crashes on certain views if they don't have binding.
return View.VISIBLE;
}
}
希望这个问题在未来得到解决,并且不需要这种解决方法!
编辑
我在https://code.google.com/p/android-developer-preview/issues/detail?id=2421 上发现了另一个关于自定义绑定适配器的问题