何时使用MutableLiveData和LiveData

62

何时使用MutableLiveDataLiveData取决于使用方法的范围:

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

何时使用此功能,

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

5
基本上,你需要将它暴露为“LiveData”以供UI(Activity/Fragment)使用,因为它不能直接修改,并将其作为“MutableLiveData”(如果在项目中使用)暴露给存储库。 - Jeel Vankhede
2
请通过一个简单的例子让我理解 - vinayak
8个回答

71

LiveData没有公共方法来修改其数据。

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

你不能像这样更新它的值:getUser().setValue(userObject)getUser().postValue(userObject)

因此,如果你不希望数据被修改,请使用 LiveData 如果你想稍后修改数据,请使用 MutableLiveData


5
你所说的无法更新实时数据值是错误的。LiveData并非同步,但MutableLiveData是同步的,并且具有使用postValue方法从Worker线程调用观察者的能力。因此,如果你不希望修改数据,请使用LiveData。如果以后需要修改数据,请使用MutableLiveData。这句话不正确。(此内容是对以下内容的翻译:https://dev59.com/zVYN5IYBdhLWcg3w1LMG) - Sohail Zahid
我不太理解你的评论,链接也重复了相同的信息。LiveData是一个抽象类,具有受保护的setValuepostValue方法,应该用于限制在活动或片段中的修改。您能否提供一个示例,在其中可以使用setValuepostValue更新LiveData值? - shb
1
但是,你不能只将返回的LiveData强制转换为MutableLiveData吗? - Tayyab Mazhar
2
作为 MVVM 初学者,我了解到 LiveDataViewModelView 之间进行通信的唯一方式。那么一个不可变的 LiveData 有什么意义呢? - Minh Nghĩa

24

假设你正在遵循MVVM架构,并使用LiveData作为从ViewModelActivity的可观察模式。如此一来,你可以将变量作为LiveData对象暴露给Activity,代码示例如下:

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

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

现在,在 Activity 部分,您可以观察到 LiveData,但是要进行修改,您可以像以下方式一样从 ViewModel 中调用方法:

而现在在Activity部分,您可以观察到LiveData,但是如果要进行修改,您可以如下所示从ViewModel中调用方法:

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
}

3
通过在ViewModel中创建两个对象,可以实现另一种方法。MutableLiveData 对象可以是私有的,并且可以通过setter方法进行操作,而公共对象可以是从上述私有对象重新分配的 LiveData。 - Jeel Vankhede
1
@JeelVankhede 你说得对,我的朋友。这是由Google开发人员制作的官方Udacity课程中推荐的方法。这是封装我们不希望类编辑的信息的方式。请查看以下课程链接:https://classroom.udacity.com/courses/ud9012 - Ramiro G.M.

16
LiveData没有公开的可用方法来更新存储的数据。 MutableLiveData类公开了setValue(T)postValue(T)方法,如果需要编辑存储在LiveData对象中的值,则必须使用这些方法。通常,在ViewModel中使用MutableLiveData,然后ViewModel仅向观察者公开不可变的LiveData对象。请参阅此参考文献

15

我们应该返回LiveData以防止视图(或其他观察者)意外修改值。

拥有:

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

在您的活动/片段中,不能编写以下代码:getUser().setValue(...)。这会使您的代码更少出现错误。


1

LiveData和MutableLiveData的主要区别是:

  • 你可以更改MutableLiveData的值,但是LiveData不允许您更改其值
  • LiveData只允许您观察其值。

它们通常一起使用。因此,MutableLiveData用于记录更改后的值,而LiveData用于通知UI有关更改值的信息。


1

在单独的类中使用MutableLiveData的最佳方法

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在Fragment中的用法如下:

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);
            }
        });
    }

在Fragment类中应该像这样。
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);
            }
        });
    }
}

0

当您不想修改数据时,请使用LiveData,因为像setValue()postValue()这样的方法不是公共的。LiveData通过在内部调用它们来自行处理。

而在MutableLiveData中,setValue()postValue()是公开的,您可以通过调用这些方法来更改设置的值。

在此处查找更多详细信息: https://blog.mindorks.com/livedata-setvalue-vs-postvalue-in-android


0
为了最佳实践和可读性,并避免出错,就像 Kotlin 中的 MutableList vs List。在需要修改其数据或想要重新分配新值时,请使用Mutable。
当我们希望使其值可写或随时更改时,我们使用MutableLiveData。
当我们只想读取并监听MutableLiveData进行的任何更新时,我们使用LiveData。 因此,我们有以下代码示例。
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

        })

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接