By default, the reader of this article has some Android development experience and a brief understanding of the Android Annotations and DataBinding technology.

The article concludes with a summary of why DataBinding’s technology should be used by comparing the code in three different ways.

function

The function of the three different codes is to dynamically control the click status of the login button on the login interface by monitoring the text changes in the user name and password input boxes.

The first is a generic implementation

If you write code in the normal way, you can find a lot of redundancy, most of which is repetitive work:

  • Instantiate view:findViewById(...)
  • Add text listener:addTextChangedListener(...)
  • Set click events:setOnClickListener(...)

The XML file has two EditTexts and a Button. This is a simple one, so instead of Posting the code here, just post the Activity code:

public class LoginNormalActivity extends AppCompatActivity {
    private EditText nameEdit;
    private EditText pwdEdit;
    private Button loginBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); .// Instantiate view
        nameEdit = (EditText) findViewById(R.id.login_name_edit);
        pwdEdit = (EditText) findViewById(R.id.login_pwd_edit);
        loginBtn = (Button) findViewById(R.id.login_btn);

        // Add text change listener
        OnTextChangeListener textChangeListener = new OnTextChangeListener();
        nameEdit.addTextChangedListener(textChangeListener);
        pwdEdit.addTextChangedListener(textChangeListener);

        // Login button click event listener
        loginBtn.setOnClickListener(v -> Toast.makeText(this."click login!", Toast.LENGTH_SHORT).show());

        updateLoginEnable();
    }

    /** * Updates the status of the login button */
    private void updateLoginEnable(a) { loginBtn.setEnabled(! (TextUtils.isEmpty(nameEdit.getText()) || TextUtils.isEmpty(pwdEdit.getText()))); }/** * Text changes Listener */
    private class OnTextChangeListener implements TextWatcher {...@Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // Update the text after it has changedupdateLoginEnable(); }}}Copy the code

The second type: Android Annotations

Writing code with annotations allows you to focus on what’s really important and makes code simpler:

  • Through annotation@ViewById @Click @AfterTextChangeSolve a lot of repetitive tasks
  • APT generates a new class at compile time, the naming rule is the original class name underlined, no reflection, will not affect the efficiency of the program to run, but the new compiled class will increase your awareness, use a little uncomfortable.

The XML file has two EditTexts and a Button, which is quite simple. Again, we don’t post any code, just post the Activity code:

@EActivity(R.layout.login_activity)
public class LoginAnnotationActivity extends AppCompatActivity {
    // Instantiate view
    @ViewById(R.id.login_name_edit)
    protected EditText nameEdit;
    @ViewById(R.id.login_pwd_edit)
    protected EditText pwdEdit;
    @ViewById(R.id.login_btn)
    protected Button loginBtn;

    @AfterViews
    protected void initView(a) {
        updateLoginEnable();
    }

    /** * Updates the status of the login button */
    private void updateLoginEnable(a) { loginBtn.setEnabled(! (TextUtils.isEmpty(nameEdit.getText()) || TextUtils.isEmpty(pwdEdit.getText()))); }/** * Login click callback */
    @Click(R.id.login_btn)
    protected void login(View view) {
        Toast.makeText(this."click login!", Toast.LENGTH_SHORT).show();
    }

    // Add text change listener
    @AfterTextChange({R.id.login_pwd_edit, R.id.login_name_edit})
    protected void afterTextChange(TextView tv, Editable text) {
        // Update the text after it has changedupdateLoginEnable(); }}Copy the code

Third: DataBinding implementation

Binding mode: The data and UI layers are decoupled based on the removal of redundant code

  • throughandroid:text="@={... }"Bind data bidirectionally to the UI
  • throughandroid:enabled="@{... }"Control button status
  • throughandroid:onClick="@{... }"Handle user action events directly
  • Generate auxiliary tool classes with APT during compilation to achieve dynamic binding of data and UI

First, the XML file code:

<?xml version="1.0" encoding="utf-8"? >
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="loginViewHelper"
            type="com.free.fastmvpdemo.login.LoginViewHelper" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingLeft="20dp"
        android:paddingRight="20dp">

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:hint="@string/account_hint"
            android:text="@={loginViewHelper.name}" />

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:hint="@string/pwd_hint"
            android:text="@={loginViewHelper.pwd}" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:enabled="@{loginViewHelper.canLogin(loginViewHelper.name,loginViewHelper.pwd)}"
            android:onClick="@{loginViewHelper.login}"
            android:text="@string/login" />
    </LinearLayout>
</layout>Copy the code

As shown in the XML code, the data binding rules are already in place. In fact, the Java code only needs to handle the business related logic, which is very clear.

public class LoginActivity extends AppCompatActivity {
    //DataBinding automatically generates classes that take XML file names and end with Binding
    LoginActivityBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {...// Initialize data bind and set the Helper instance
        binding = DataBindingUtil.setContentView(this, R.layout.login_activity);
        binding.setLoginViewHelper(newLoginViewHelper()); }}public class LoginViewHelper {
        // Listen for attributes
        public ObservableField<String> name = new ObservableField<>();
        public ObservableField<String> pwd = new ObservableField<>();

        /** * Login click callback */
        public void login(View view) {
            Toast.makeText(view.getContext(), "click login!", Toast.LENGTH_SHORT).show();
        }

        /** * Whether to log in */
        public boolean canLogin(String name, String pwd) {
            return !(TextUtils.isEmpty(name) || TextUtils.isEmpty(pwd));
        }
    }Copy the code

conclusion

  • Common approach: Too much redundant code, so we should abandon common approach and embrace new technology
  • Annotation method: through annotation to solve the vast majority of repetitive work, and no reflection, does not affect the efficiency of the program, just need to recognize some classes, use a little uncomfortable. However, in some Activity jump broadcast receivers, annotations have a natural advantage in making your code clearer.
  • Binding mode: Data-driven: Automatically updates the UI after data changes; Event handling: Directly find the target instance to handle the event of the user’s action. This way we don’t need to deal with the UI or controls, we just need to handle the business logic in Java code, very clear, and leave the rest to the Binding library. This reduces code coupling and makes data independent of the UI, which has a positive impact on future program changes and maintenance. Think long term about the preferred binding method.

One final note: Android bindings are still a bit behind the angularJS front end, especially when it comes to bidirectional binding, and Android Studio’s support for DataBinding error reporting and automatic code generation is not very friendly. Of course, this is just the status quo, and it will get better.