Avoid loop in MVVM Pattern

Viewed 86

i am trying to learn MVVM Pattern with my Activity and a ViewModel.

Now, assume that i have an EditText in my layout. Once i edit that field i write that data immediatly to the ViewModel which triggers the Observer which triggers the update of the Field which repeats the cycle anew.

Example:

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) {

            }
        });
    }
}

And the ViewModel

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

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

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

My current solution are two boolean flags overrideListener and overrideViewModel. Whenever i set the text from the ui i set overrideViewModel to true and reset it in the observer. Or the other way round if the value is set by the viewModel i check in the text change listener if it should execute.

This seems to be an antipattern. Something so trivial should not be so difficult and so much writing effort should it?

I hope my question is clear enough and you can explain my mistake:)

1 Answers

You can modify your setText method like this,

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

Basically, set new value only if it's different than current value.

Related