Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/204.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 避免MVVM模式中的循环_Java_Android_Mvvm_Viewmodel - Fatal编程技术网

Java 避免MVVM模式中的循环

Java 避免MVVM模式中的循环,java,android,mvvm,viewmodel,Java,Android,Mvvm,Viewmodel,我试图通过我的活动和ViewModel学习MVVM模式 现在,假设我的布局中有一个EditText。编辑该字段后,我会立即将该数据写入ViewModel,从而触发观察者,从而触发字段更新,并重新重复该循环 例如: public class TestFragment extends Fragment { private FragmentTestBinding b; private TestViewModel mViewModel; @Override publi

我试图通过我的活动和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) {

            }
        });
    }
}
以及ViewModel

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

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

    void setText(String text) {
        mEditText.setValue(text);
    }
}
公共类TestViewModel扩展了ViewModel{
私有MutableLiveData mEditText=新的MutableLiveData();
LiveData getText(){
返回mEditText;
}
void setText(字符串文本){
mEditText.setValue(文本);
}
}
我当前的解决方案是两个布尔标志
overrideListener
overrideViewModel
。每当我从ui设置文本时,我都会将overrideViewModel设置为true,并在observer中重置它。或者反过来说,如果该值是由viewModel设置的,我会在文本更改侦听器中检查它是否应该执行

这似乎是一个反模式。如此琐碎的事情不应该如此困难,那么多的写作努力应该是吗


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

您可以像这样修改
setText
方法

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

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

我以前使用过类似的方法,但这不起作用,这就是我现在使用标志的原因。你的方法有问题。如果我编辑文本,它已更改,viewmodel将更新并触发observer,然后将代码重写为用户当前编辑的编辑文本。问题是:如果用户的编辑速度更快怎么办?更大的问题是:以编程方式写入文本字段会将光标重置为一个位置。因此,这可以防止用户键入。我用旗子的解决方案是可行的,但它看起来太复杂了。没有更简单的办法吗?