问题
I am trying to define an attribute for any view using the Data Binding Library, as explained in this Android Developers post.
To do so, the post says one first needs a layout with an enclosing <layout>
tag:
<?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>
At this point, the layout caused a ClassNotFoundException when inflated. The only way I found to get rid of it was to add a <data></data>
node, even if it was absent from the Android Developers post:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data></data>
...
</layout>
(The post does not mention it, but I had to enable dataBinding
in my build.gradle
as recommended in the Guide before I could build.)
The post then explains how to write a BindingAdapter
method to process the attribute:
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);
}
}
However, the bindAttribute
method is never called. I do see the generated code for the layout in my build folder, but nothing else happens.
Why is my BindingAdapter ignored?
回答1:
I found the solution to my problem, I was not creating the Binding correctly:
Following the first steps of the Guide, I used DataBindingUtil.setContentView
, but for ListView
items you need to use ItemBinding.inflate
in the Adapter
'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());
}
回答2:
From what I can tell in that first link, the data
tag is present. It was probably omitted in the G+ post because its boilerplate. In fact, in the docs it says
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.
Anyways, I think you might be missing some required sugar in the layout file. Can you try:
app:attribute='@{"name"}`
Maybe its required for the binding to occur. I mean right now I am aiming blind until I actually test this. But from that post I see app:imageUrl='@{"http://example.com/image.jpg"}'
.
回答3:
It should be @BindingAdapter("bind:attribute")
instead of @BindingAdapter("app:attribute")
and try with this, it might work.
app:attribute="@{`name`}"
来源:https://stackoverflow.com/questions/37118779/why-is-this-custom-view-attribute-ignored