【问题标题】:Avoid loop in MVVM Pattern避免 MVVM 模式中的循环
【发布时间】:2020-12-24 14:26:07
【问题描述】:

我正在尝试通过我的 Activity 和 ViewModel 学习 MVVM 模式。

现在,假设我的布局中有一个 EditText。一旦我编辑了该字段,我立即将该数据写入 ViewModel 触发观察者触发更新重复循环的字段。

例子:

public class TestFragment extends Fragment {
    private FragmentTestBinding b;
    private TestViewModel mViewModel;


    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        b = FragmentTestBinding.inflate(inflater, container, false);
        return b.getRoot();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        initViewModel();
        initListener();
    }


    private void initViewModel() {
        mViewModel = new ViewModelProvider(this).get(TestViewModel.class);
        mViewModel.getText().observe(getViewLifecycleOwner(), this::onTextFieldChanged);
    }

    void onTextFieldChanged(String text) {
        b.editText.setText(text);
    }

    void initListener() {
        b.editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                mViewModel.setText(charSequence.toString());
            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });
    }
}

还有视图模型

public class TestViewModel extends ViewModel {
 private MutableLiveData<String> mEditText = new MutableLiveData<>();

    LiveData<String> getText() {
        return mEditText;
    }

    void setText(String text) {
        mEditText.setValue(text);
    }
}

我当前的解决方案是两个布尔标志 overrideListeneroverrideViewModel。每当我从 ui 设置文本时,我将 overrideViewModel 设置为 true 并在观察者中将其重置。或者相反,如果值是由 viewModel 设置的,我会检查文本更改侦听器是否应该执行。

这似乎是一种反模式。这么琐碎的事情不应该这么难,应该这么费劲吗?

我希望我的问题足够清楚,你可以解释我的错误:)

【问题讨论】:

    标签: java android mvvm viewmodel


    【解决方案1】:

    你可以像这样修改你的setText方法,

    void setText(String text) {
        if (text != mEditText.getValue())
            mEditText.setValue(text);
    }
    

    基本上,只有当它与当前值不同时才设置新值。

    【讨论】:

    • 我以前用过类似的东西,但这不起作用,这就是我现在使用标志的原因。你的方法的问题。如果我编辑文本,它已经改变,视图模型被更新并且观察者被触发,然后将代码重写为用户当前编辑的编辑文本。这样做的问题是:如果用户的编辑速度更快怎么办?更大的问题是:以编程方式写入文本字段会将光标重置为第一个位置。所以这可以防止用户打字。我的标志解决方案有效,但看起来很复杂。没有更简单的方法吗?
    猜你喜欢
    • 2022-12-05
    • 1970-01-01
    • 1970-01-01
    • 2015-10-29
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    • 2014-01-24
    相关资源
    最近更新 更多