How can I do databinding with livedata?

后端 未结 1 920
旧巷少年郎
旧巷少年郎 2020-12-16 23:15

How can I do databinding with livedata?

activity_user_detail.xml:


    

        
相关标签:
1条回答
  • 2020-12-16 23:43

    This is a sample to figure out how LiveData and ObservableField works. You need to change T object and setValue() with LiveData, or set(T) with ObservableField. Changing properties of object T does not update UI.

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <data>
    
            <variable
                name="viewModel"
                type="com.example.tutorial3livedata_databinding2objects.UserViewModel" />
        </data>
    
        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <TextView
                android:id="@+id/user_info"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text='@{viewModel.userMutableLiveData.name+ ", email " + viewModel.userMutableLiveData.email}'
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintHorizontal_bias="0.501"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintVertical_bias="0.1" />
    
            <EditText
                android:id="@+id/et_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="8dp"
                android:layout_marginTop="48dp"
                android:text="@={viewModel.userMutableLiveData.name}"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.501"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/user_info" />
    
            <EditText
                android:id="@+id/et_email"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginEnd="8dp"
                android:layout_marginStart="8dp"
                android:layout_marginTop="28dp"
                android:text="@={viewModel.userMutableLiveData.email}"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.501"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/et_name" />
    
            <Button
                android:id="@+id/button_change_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="32dp"
                android:onClick="@{() -> viewModel.changeUserName()}"
                android:text="Change Name"
                app:layout_constraintEnd_toStartOf="@+id/button_change_user"
                app:layout_constraintHorizontal_chainStyle="spread"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/et_email" />
    
            <Button
                android:id="@+id/button_change_user"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="@{() -> viewModel.changeUser()}"
                android:text="Change User"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toEndOf="@+id/button_change_name"
                app:layout_constraintTop_toTopOf="@+id/button_change_name" />
    
            <Button
                android:id="@+id/button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="56dp"
                android:text="Display User"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/button_change_name" />
    
        </android.support.constraint.ConstraintLayout>
    </layout>
    

    ViewModel

    public class UserViewModel extends ViewModel {
    
        public MutableLiveData<User> userMutableLiveData = new MutableLiveData<>();
        private User mUser;
    
        public UserViewModel() {
            mUser = new User("User", "asd@abc.com");
            userMutableLiveData.setValue(mUser);
    
        }
    
        public void changeUserName() {
    
            // Both updates LiveData but does not update UI
            mUser.setName("Name is Changed");
            // userMutableLiveData.getValue().setName("Updated Name");
    
            // This one Updates UI
            //  userMutableLiveData.setValue(userMutableLiveData.getValue());
        }
    
        public void changeUser() {
            mUser = new User("New User Name", "myemail@mail.com");
            // Without setting new value UI is not updated and observe is not called
            userMutableLiveData.setValue(mUser);
        }
    }
    

    MainActivity

    /*
        Without binding.setLifecycleOwner(this), liveData.setValue() does not update UI
        liveData.setValue() updates UI 
        EditText changes LiveData but does not update UI
     */
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            final ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
            UserViewModel userViewModel = ViewModelProviders.of(this).get(UserViewModel.class);
            // LiveData should call setValue() to update UI via binding
            binding.setViewModel(userViewModel);
    
            // Required to update UI with LiveData
            binding.setLifecycleOwner(this);
        }
    }
    

    This code is for learning purposes.

    Results you can get from this code:

    1- Changing user name with changeUserName() updates the name of existing User of LiveData but does not update UI. UI gets updated when you rotate the device.

    2- When you change User of LiveData and setValue() data-binding works.

    3- Changing User properties using EditText 2-way binding android:text="@={viewModel.userMutableLiveData.name}" changes LiveData's User's name but does not update UI until device is rotated since User is still same.

    0 讨论(0)
提交回复
热议问题