【问题标题】:The inflate method for my binding is not found (using Android, Data Binding.)找不到我的绑定的 inflate 方法(使用 Android,数据绑定。)
【发布时间】:2016-08-01 19:48:49
【问题描述】:

我正在使用数据绑定来绑定我的 Android 应用中的布局。

我已经设置好我的布局(my_custom.xml)并生成了绑定类(MyCustomBinding),但是Android Studio似乎并没有马上找到Binding类的.inflate(...)方法,标记一下作为一个错误(红色文本!)。

不过,代码似乎是正确的,因为它可以很好地编译并构建到 APK 中。

如何让 Android Studio 正确更新?

代码示例:

这是我的自定义视图代码:

    public class MyCustomView extends FrameLayout {
    public MyCustomView(Context context) {
        this(context, null, 0);
    }
    public MyCustomView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        MyCustomBinding binding = MyCustomBinding.inflate(inflater, this, true);
        binding.aButton.setText("Whatever");
    }
}

布局定义为:

    <?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
    </data>
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
        <TextView
            android:id="@+id/a_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Click me!"
            android:padding="10dp"
            android:background="#000"
            android:textColor="#fff"
            android:layout_gravity="center"
            />
    </FrameLayout>
</layout>

这就是问题所在:(以红色突出显示)

【问题讨论】:

  • 请发布您的代码。你用的是Activity还是Fragment?
  • 发布“MyCutomBinding”类代码。
  • 这在我看来是 Android Studio 2.2 中的一个错误。几个月来我一直在使用没有这个问题的数据绑定,直到今天升级,现在我也看到了。有bug report,如果你想关注它。

标签: android android-layout android-databinding


【解决方案1】:

由于您尚未实际实现数据绑定,Android Studio 中的某些内容未完成。 将变量添加到布局的 data 元素后,inflate 方法将如您所愿找到。也就是说,通过绑定直接设置文本字段的值,您实际上并没有获得数据绑定的好处。相反,您应该在绑定中设置视图模型,然后让绑定相应地更新视图。例如:

创建一个视图模型:

public class MyViewModel {
    public final ObservableField<String> name;
    public MyViewModel(String name) {
        this.name = new ObservableField<>(name);
    }
}

并在你的布局中使用它

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="model" type="com.victoriaschocolates.conceirge.MyViewModel" />
    </data>
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{model.name}"
            android:padding="10dp"
            android:background="#000"
            android:textColor="#fff"
            android:layout_gravity="center"
            />
    </FrameLayout>
</layout>

(注意data 元素中声明的variable,以及它在TextView 的text 属性中的引用方式)

然后在您的自定义视图中绑定两者:

public class MyCustomView extends FrameLayout {

    public MyCustomView(Context context) {
        this(context, null, 0);
    }

    public MyCustomView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        MyCustomBinding binding = MyCustomBinding.inflate(inflater, this, true);
        MyViewModel model = new MyViewModel("Whatever");
        binding.setModel(model);
    }
}

当然,最好还是让数据通过自定义视图类中的 setter 传入,甚至从容器视图传入(参见 http://developer.android.com/tools/data-binding/guide.html#includes

【讨论】:

  • 谢谢!是的,我意识到使用数据绑定的预期方法是使用模式广告,然后在 xml 中绑定值。我发现有时只在代码中进行绑定而不是创建模型对象等更容易。
  • 我现在的解决方案是定义一个空模型类:public class EmptyModel {},然后将其定义为变量 [[ ]],而不将其实际绑定到任何视图。
【解决方案2】:

您可以尝试为您的绑定布局设置一个自定义类名,并在您的自定义视图中引用它以明确您使用的布局:

<layout>
    <data class="MyCustomBinding">
    </data>
</layout>

如果这不起作用,请使用DataBindingUtil 而不是MyCustomBinding,它返回基本的DataBinding 类并具有inflate() 方法:

MyCustomBinding binding = DataBindingUtil.inflate(inflater, this, true);

来自docs

有时无法提前知道绑定。在这种情况下,可以使用 DataBindingUtil 类创建绑定:

ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater, layoutId,
parent, attachToParent);
ViewDataBinding binding = DataBindingUtil.bindTo(viewRoot, layoutId);

【讨论】:

  • 感谢您的回答。我不相信这会以最好的方式回答我的问题。我认为这不是 MyCustomBinding 未知的情况之一。我在 Android Studio 中 导入该类,它确实可以编译。奇怪的是 .inflate() 方法无法识别。
  • 它编译了吗?哦。我的错 - 但你有没有尝试在 xml 中设置类?
  • 是的,它确实可以编译。我相信这主要是Android Studio中的一个问题。我尝试在 xml 中设置类。虽然这允许我更改绑定的类名,但遗憾的是它并不能解决问题。
【解决方案3】:

这是基于最新数据绑定和 androidx 的更新答案,我来这里是为了解决我自己的问题,在看了上面的答案之后,我通过自己的工作代码 sn-p 开发。希望这会有所帮助

    public class CustomActionBar1 extends RelativeLayout {

    public MutableLiveData<String> title = new MutableLiveData<>("Sample text");
    CustomActionBar1Binding binding;

    public CustomActionBar1(Context context) {
        super(context);
        init(context, this);
    }

    public CustomActionBar1(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, this);
    }

    public CustomActionBar1(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, this);
    }

    public CustomActionBar1(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, this);
    }

    private void init(Context context, ViewGroup viewGroup) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        binding = DataBindingUtil.inflate(inflater, R.layout.custom_action_bar_1, viewGroup, true);
    }

    // helper to change title
    public void changeTitle(String title) {
        if (title != null)
            this.title.setValue(title);
    }

    public void setTitleVisibility(Boolean visibile){
        binding.titleText.setVisibility(visibile ? View.VISIBLE : View.INVISIBLE);
    }

}

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">

    <data>
        <variable
            name="customActionBar1"
            type="com.actionBar.CustomActionBar1" />
    </data>

    <RelativeLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:background="@color/yellow"
        android:layout_height="@dimen/action_bar_height"
        android:id="@+id/main_header_relative">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:text="@{customActionBar1.title}"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:id="@+id/titleText"
        android:visibility="visible"
         android:textColor="@color/black" />


    </RelativeLayout>
</layout>

【讨论】:

    【解决方案4】:

    你不需要那种东西,DataBinding 包括 DataBindingUtils 类在这里我们去。

    public MyCustomView(Context context, AttributeSet attrs, int defStyle){
        super(context, attrs, defStyle);
        LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        MyCustomBinding binding = DataBindingUtil.inflate(inflater, this, true);
        binding.aButton.setText("Whatever");
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-13
      • 2018-06-25
      • 1970-01-01
      • 1970-01-01
      • 2016-10-12
      • 2019-08-21
      • 2018-10-23
      • 2020-09-21
      相关资源
      最近更新 更多