vinayak
vinayak

Reputation: 663

When to use MutableLiveData and LiveData

when to use MutableLiveData and LiveData means the area of using the methods :

MutableLiveData<User> getUser() {
    if (userMutableLiveData == null) {
        userMutableLiveData = new MutableLiveData<>();
    }
    return userMutableLiveData;
}

and when to use this,

LiveData<User> getUser() {
    if (userMutableLiveData == null) {
        userMutableLiveData = new MutableLiveData<>();
    }
    return userMutableLiveData
}

Upvotes: 64

Views: 87284

Answers (8)

The main difference between LiveData and MutableLiveData is:

  • you can change the value of MutableLiveData but LiveData does not allow you to change it's value
  • LiveData only allows you to observe its value.

They are usually used together. so MutableLiveData is used to record the changed value and LiveData is used to notify the UI about the change value.

Upvotes: 1

Siddhesh Chandorkar
Siddhesh Chandorkar

Reputation: 171

LiveData has no public available methods to update the stored data. The MutableLiveData class exposes the setValue(T) and postValue(T) methods public and you must use these if you need to edit the value stored in a LiveData object. Usually MutableLiveData is used in the ViewModel and then the ViewModel only exposes immutable LiveData objects to the observers. Please take a look at this reference.

Upvotes: 17

Undefined function
Undefined function

Reputation: 868

For best practice, readability and avoid error prone by mistake just like MutableList vs List in Kotlin. Use Mutable is when you want its data to be modified or you want to re assign a new value on it.

We use MutableLiveData when we want to make its value writable or can be change anytime.

We use LiveData when we just want to read and listen to any updates made by MutableLiveData. Thus we have this kind of code as sample

private var filterAsset = MutableLiveData<String>().apply{
        value = "Empty"
    }

    //public method to set a new value on filterAsset
    fun setFilterData(assetName: String){
        filterAsset.value = assetName
    }

// We can use this to listen on any updates from filterAsset
val assetFilterUpdates: LiveData<String> = filterAsset


// Inside your Fragment/Activity
// You can listen to the update in Fragment or Activity like this 
yourViewModel.assetFilterUpdates.observe(viewLifecycleOwner, { value ->

            // Use the updated value here

        })

Upvotes: 0

pankaj jha
pankaj jha

Reputation: 49

Best Approach of using MutableLiveData in seprate class Like

public class SharedViewModel extends ViewModel {
private MutableLiveData<CharSequence>text = new MutableLiveData<>();

public void setText(CharSequence input)
{
    text.setValue(input);
}

public LiveData<CharSequence> getText(){
    return text;

}
}

Livedata is Used in Fragment Like

private SharedViewModel viewModel;

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        //No Need to initate further
        viewModel = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
        viewModel.getText().observe(getViewLifecycleOwner(), new Observer<CharSequence>() {
            @Override
            public void onChanged(@Nullable CharSequence charSequence) {
                editText.setText(charSequence);
            }
        });
    }

in Fragment Class be Like

public class FragmentA extends Fragment {
    private SharedViewModel viewModel;
    private EditText editText;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_a, container, false);
        editText = v.findViewById(R.id.edit_text);
        Button button = v.findViewById(R.id.button_ok);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                viewModel.setText(editText.getText());
            }
        });
        return v;
    }
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        viewModel = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
        viewModel.getText().observe(getViewLifecycleOwner(), new Observer<CharSequence>() {
            @Override
            public void onChanged(@Nullable CharSequence charSequence) {
                editText.setText(charSequence);
            }
        });
    }
}

Upvotes: 1

Ajay Chauhan
Ajay Chauhan

Reputation: 1551

Use LiveData when you don't want to modify it because the methods like setValue() & postValue() are not public .Live data takes care itself by calling them internally.

Where as in MutableLiveData setValue() postValue() are exposed ie public.You can change set values by calling these methods.

Find more details here : https://blog.mindorks.com/livedata-setvalue-vs-postvalue-in-android

Upvotes: 0

Derek K
Derek K

Reputation: 3157

We should return LiveData in order to prevent views (or other observers) from accident value modification.

Having:

    LiveData<User> getUser() {
       if (userMutableLiveData == null) {
           userMutableLiveData = new MutableLiveData<>();
       }
       return userMutableLiveData
    }

you can't write in your activity / fragment: getUser().setValue(...). This makes your code less bug prone.

Upvotes: 15

shb
shb

Reputation: 6277

LiveData has no public method to modify its data.

LiveData<User> getUser() {
    if (userMutableLiveData == null) {
        userMutableLiveData = new MutableLiveData<>();
    }
    return userMutableLiveData
}

You can't update its value like getUser().setValue(userObject) or getUser().postValue(userObject)

So when you don't want your data to be modified use LiveData If you want to modify your data later use MutableLiveData

Upvotes: 76

Jeel Vankhede
Jeel Vankhede

Reputation: 12118

Let's say you're following MVVM architecture and having LiveData as observable pattern from ViewModel to your Activity. So that you can make your variable as LiveData object exposing to Activity like below :

class MyViewModel : ViewModel() {
    // LiveData object as following
    var someLiveData: LiveData<Any> = MutableLiveData()

    fun changeItsValue(someValue: Any) {
        (someLiveData as? MutableLiveData)?.value = someValue
    }
}

And now at Activity part, you can observe LiveData but for modification you can call method from ViewModel like below :

class SomeActivity : AppCompatActivity() {
    // Inside onCreateMethod of activity
    val viewModel = ViewModelProviders.of(this)[MyViewModel::class.java]
    viewModel.someLiveData.observe(this, Observer{
        // Here we observe livedata
    })
    viewModel.changeItsValue(someValue) // We call it to change value to LiveData
    // End of onCreate
}

Upvotes: 24

Related Questions