title: Android 2-Way DataBinding With Custom View and Custom Attr
body: <p>I've been using 2-way databinding for a basic application, it was going pretty well, until i start with custom views and attrs.</p>
  
  <p>I want to create a custom view, with has a TextView and a EditText, and use it inside another layout:</p>
  
  <pre><code> &lt;TextView
      android:text="Holder"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/tvTitle"
      android:layout_weight="1" /&gt;
  
  &lt;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" /&gt;
  </code></pre>
  
  <p>And i have the custom attr for it</p>
  
  <pre><code>&lt;resources&gt;
  &lt;declare-styleable name="form_item"&gt;
      &lt;attr name="tvTitle" format="string" /&gt;
      &lt;attr name="anwserHint" format="string" /&gt;
      &lt;attr name="anwserText" format="string" /&gt;
      &lt;attr name="android:enabled" /&gt;
  &lt;/declare-styleable&gt;
  </code></pre>
  
  <p></p>
  
  <p>In the fragment i do the following:</p>
  
  <pre><code> &lt;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:" /&gt;
  </code></pre>
  
  <p>It works nice has 1-way databind, but whatever i change the text, he don't send me the callback in class</p>
  
  <pre><code>@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);
      }
  }
  </code></pre>
  
  <p>Does anyone know how to make it work properly?</p>
  
  <p>Fully code can be found at <a href="https://github.com/Klauswk/FinancialControl" rel="noreferrer">here</a></p>