我有一个Java数据绑定布局,正在另一个Java数据绑定布局中使用。单独查看时,子组件可以正确呈现,但是当我在设计视图中查看超级组件时,它不会呈现子组件,并且在“无法实例化一个或多个类”下的设计视图错误面板中具有空引用错误。它会编译并按预期运行。在自动生成的BindingImpl文件中查看,未生成任何使用数据绑定的视图的引用,因此引用错误。如何获得子组件以正确实例化?

如果我从xml中删除所有数据绑定并放入代码中,则该组件将在设计视图中正确显示(但达不到使用它的目的的一半)。工程正确编译,没有错误,尽管设计视图指出还有“无法实例化...”错误

[自动生成] ComponentNumberPickerBindingImpl.java

static {
        sIncludes = null;
        sViewsWithIds = new android.util.SparseIntArray();
        sViewsWithIds.put(R.id.number_picker_minus_button, 2);
        sViewsWithIds.put(R.id.number_picker_plus_button, 3);
    }

private ComponentNumberPickerBindingImpl(androidx.databinding.DataBindingComponent bindingComponent, View root, Object[] bindings) {
        super(bindingComponent, root, 1
            , (android.widget.ImageButton) bindings[2]
            , (android.widget.ImageButton) bindings[3]
            , (android.widget.TextView) bindings[1]
            );
        this.mboundView0 = (android.widget.LinearLayout) bindings[0];
        this.mboundView0.setTag(null);
        this.numberPickerText.setTag(null); // java.lang.NullPointerException error here
        setRootTag(root);
        // listeners
        invalidateAll();
    }


component_number_picker.xml

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <data>

        <variable
            name="numberPicker"
            type="shared.NumberPicker" />

        <variable
            name="target"
            type="androidx.lifecycle.MutableLiveData&lt;Integer>" />
    </data>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ImageButton
            android:id="@+id/number_picker_minus_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:background="@drawable/border_circular"
            android:contentDescription="@string/desc_remove_large_luggage_button"
            android:src="@drawable/ic_remove_24px" />

        <TextView
            android:id="@+id/number_picker_text"
            style="@style/TextAppearance.AppCompat.Large"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center"
            android:minWidth="60dp"
            android:textAlignment="center"
            tools:text="9"
            android:text="@{`` + target}"/>

        <ImageButton
            android:id="@+id/number_picker_plus_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:background="@drawable/border_circular"
            android:contentDescription="@string/desc_add_large_luggage_button"
            android:src="@drawable/ic_add_24px" />

    </LinearLayout>
</layout>


NumberPicker.java

package shared;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.LinearLayout;

import androidx.lifecycle.MutableLiveData;

import databinding.ComponentNumberPickerBinding;

public class NumberPicker extends LinearLayout {

    ComponentNumberPickerBinding mBinding;

    public NumberPicker(Context context) {
        super(context);
        initialiseViews(context);
    }

    public NumberPicker(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialiseViews(context);
    }

    public NumberPicker(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initialiseViews(context);
    }

    private void initialiseViews(Context context) {
        mBinding = ComponentNumberPickerBinding.inflate(LayoutInflater.from(context), this, true);
        mBinding.setNumberPicker(this);
    }

    public MutableLiveData<Integer> getTarget() {
        return mBinding.getTarget();
    }

    public void setTarget(MutableLiveData<Integer> value) {
        mBinding.setTarget(value);
    }

}



包括

<shared.NumberPicker
            android:id="@+id/luggage_specifier_number_picker"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

最佳答案

因此,我相信这是在设计视图中使用数据绑定代码中的错误。我在应用程序代码运行时跟踪了该代码,并注意到它正在为子组件中的每个视图分配一个标签(我看不到它发生的位置,大概是在DataBinding设置中的某个地方)。类,以在绑定实现中分配给视图属性。

但是,在使用设计视图时,这些标签似乎没有被设置,因此这些视图永远不会添加到视图绑定数组中,因此也永远不会分配给视图属性。

我发现了一种解决方法,可以手动分配标签(例如,binding_1,binding_2等)。构建代码时,它会找到标签并正确分配它们,并且视图将按预期方式呈现。

更新
经过更多的挖掘之后,似乎绑定标签已在其中,但由于某种原因它没有被拾取-这两个布局均来自自动生成的component_number_picker.xml。
请注意,TextView具有“ originalTag”属性,而ImageView没有。在此示例中,我在布局xml中将标签添加到了TextView,但没有将ImageView添加到标签。在设计视图中查看时,TextView可以正确实例化,但是ImageView会导致NullReferenceError。

<Target id="@+id/number_picker_text" originalTag="binding_2" tag="binding_2"
            view="TextView">
            <Expressions>
                <Expression attribute="android:text" text="`` + target">
                    <Location endLine="50" endOffset="40" startLine="50" startOffset="12" />
                    <TwoWay>false</TwoWay>
                    <ValueLocation endLine="50" endOffset="38" startLine="50" startOffset="28" />
                </Expression>
            </Expressions>
            <location endLine="51" endOffset="36" startLine="40" startOffset="8" />
        </Target>
        <Target id="@+id/number_picker_plus_button" tag="binding_3" view="ImageButton">
            <Expressions>
                <Expression attribute="android:onClick" text="()-&gt;numberPicker.increment(1)">
                    <Location endLine="61" endOffset="61" startLine="61" startOffset="12" />
                    <TwoWay>false</TwoWay>
                    <ValueLocation endLine="61" endOffset="59" startLine="61" startOffset="31" />
                </Expression>
            </Expressions>
            <location endLine="61" endOffset="63" startLine="53" startOffset="8" />
        </Target>

08-06 03:13