为什么忽略此自定义视图属性?

Why is this custom view attribute ignored?

我正在尝试使用 Data Binding Library, as explained in this Android Developers post.

为任何视图定义属性

要做到这一点,post 说首先需要一个带有封闭 <layout> 标签的布局:

<?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">
    <LinearLayout android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView android:id="@android:id/text1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:attribute='@{"name"}'/>
    </LinearLayout>
</layout>

至此,。我发现摆脱它的唯一方法是添加一个 <data></data> 节点,即使 Android 开发人员不存在它 post:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
    <data></data>
    ...
</layout>

(post 没有提到它,但我必须在构建之前按照 Guide 中的建议在我的 build.gradle 中启用 dataBinding。)

然后post说明如何写一个BindingAdapter方法来处理属性:

import android.databinding.BindingAdapter;
import android.util.Log;
import android.view.View;

public class AttributesBindingAdapter {
    @BindingAdapter("bind:attribute")
    public static void bindAttribute(View view, String attributeName){
        Log.e("PLN", attributeName);
    }
}

但是,从未调用 bindAttribute 方法。我确实在我的构建文件夹中看到了为布局生成的代码,但没有其他任何反应。

为什么我的 BindingAdapter 被忽略了?

据我所知,第一个 link 中存在 data 标记。它可能在 G+ post 中被省略,因为它是样板文件。事实上,在文档中它说

Data-binding layout files are slightly different and start with a root tag of layout followed by a data element and a view root element.

无论如何,我认为您可能在布局文件中遗漏了一些必需的糖分。你能试试吗:

app:attribute='@{"name"}`

可能是绑定发生所必需的。我的意思是,在我真正测试这个之前,我现在是盲目的。但是从 post 我看到 app:imageUrl='@{"http://example.com/image.jpg"}'.

应该是@BindingAdapter("bind:attribute")而不是@BindingAdapter("app:attribute")

尝试一下,它可能会起作用。

app:attribute="@{`name`}"

我找到了问题的解决方案,我没有正确创建绑定:

按照 Guide 的第一步,我使用了 DataBindingUtil.setContentView,但是对于 ListView 项,您需要在 Adapter 中使用 ItemBinding.inflate' s ViewHolder:

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    ViewDataBinding binding = DataBindingUtil.inflate(
            LayoutInflater.from(parent.getContext()),
                    R.layout.item, parent, false);
    return new ViewHolder(binding.getRoot());
}