Enlace de datos bidireccional de Android con vista personalizada y atributo personalizado

He estado usando el enlace de datos bidireccional para una aplicación básica, iba bastante bien, hasta que comencé con vistas y atributos personalizados.

Quiero crear una vista personalizada, con TextView y EditText, y usarla dentro de otro diseño:

 <TextView
    android:text="Holder"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/tvTitle"
    android:layout_weight="1" />

<EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:inputType="none"
    android:text="Name"
    android:ems="10"
    android:id="@+id/etAnwser"
    android:layout_weight="1" />

Y tengo el atributo personalizado para ello

<resources>
<declare-styleable name="form_item">
    <attr name="tvTitle" format="string" />
    <attr name="anwserHint" format="string" />
    <attr name="anwserText" format="string" />
    <attr name="android:enabled" />
</declare-styleable>

En el fragmento hago lo siguiente:

 <rhcloud.com.financialcontrol.tabutil.FormItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:enabled="@{state.get()}"
            form_item:anwserText='@={expense.description}'
            form_item:tvTitle="Description:" />

Funciona bien tiene enlace de datos de 1 vía, pero sea lo que sea que cambie el texto, no me envía la devolución de llamada en clase

@InverseBindingMethods(value = {
        @InverseBindingMethod(type = FormItem.class, attribute = "anwserText"),
})
public class FormItem extends LinearLayout {

    private TextView tvTitle;
    private EditText etAnwser;

    public FormItem(@NonNull Context context) {
        super(context);
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        inflater.inflate(R.layout.form_item, this);

        tvTitle = (TextView) findViewById(R.id.tvTitle);
        etAnwser = (EditText) findViewById(R.id.etAnwser);
    }

    public FormItem(@NonNull Context context, @NonNull String title) {
        this(context);
        setTvTitle(title);
    }

    public FormItem(@NonNull Context context, @NonNull String title, @NonNull String hint) {
        this(context, title);
        setAnwserHint(hint);
    }

    public FormItem(@NonNull Context context, @NonNull String title, @NonNull String hint, @NonNull String anwserText) {
        this(context, title, hint);
        setAnwserHint(anwserText);
    }


    public FormItem(@NonNull Context context, @NonNull AttributeSet attrs) {
        super(context, attrs);

        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        inflater.inflate(R.layout.form_item, this);

        tvTitle = (TextView) findViewById(R.id.tvTitle);
        etAnwser = (EditText) findViewById(R.id.etAnwser);

        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.form_item,
                0, 0);

        try {
            setTvTitle(a.getString(R.styleable.form_item_tvTitle));
            setAnwserHint(a.getString(R.styleable.form_item_anwserHint));
            setAnwserText(a.getString(R.styleable.form_item_anwserText));
            String isEnabled = a.getString(R.styleable.form_item_android_enabled);
            if (isEnabled != null) {
                setEnable(Boolean.parseBoolean(isEnabled));
            }
        } finally {
            a.recycle();
        }
    }

    public void setTvTitle(String title) {
        tvTitle.setText(title);
    }

    public String getTvTitle() {
        return tvTitle.getText().toString();
    }

    public void setAnwserHint(String hint) {
        etAnwser.setHint(hint);
    }

    public String getAnwserHint() {
        return etAnwser.getHint().toString();
    }

    public void setEnable(boolean isEnable) {
        tvTitle.setEnabled(isEnable);
        etAnwser.setEnabled(isEnable);
    }

    public void setAnwserText(String anwserText) {
        etAnwser.setText(anwserText);
    }

    public String getAnwserText() {
        return etAnwser.getText().toString();
    }

    @InverseBindingAdapter(attribute = "form_item:anwserText")
    public static String setOnAnwserTextAttrChanged(final String value){

        Log.d("Test","Calling InverseBindingAdapter: " + value);
        return value;
    }


    @BindingAdapter(value = {"anwserTextAttrChanged"},
            requireAll = false)
    public static void setOnAnwserTextAttrChanged(final FormItem view,final InverseBindingListener anwserTextAttrChanged){

        Log.d("Test","Calling BindingAdapter: " + view.getAnwserText());


    if(anwserTextAttrChanged == null){

        }else{
        Log.d("Test","Calling here");
            anwserTextAttrChanged.onChange();

        }
    }

    @BindingAdapter(value = {"android:enabled"})
    public static void customEnable(FormItem formItem, boolean isEnable) {
        formItem.setEnable(isEnable);
    }
}

¿Alguien sabe cómo hacer que funcione correctamente?

El código completo se puede encontrar enaquí

Respuestas a la pregunta(1)

Su respuesta a la pregunta