I use two-way data binding for the base application, it was very good until I started with user views and attrs.
I want to create a custom view that has a TextView and an EditText, and use it inside another layout:
<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" />
And I have a custom attr for it
<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>
In the snippet, I do the following:
<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:" />
This works well with 1-way databind, but no matter what I change the text, it does not send me a callback in the class
@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); } }
Does anyone know how to make it work correctly?
Full code can be found on here.