В моем приложении есть рабочий код, который кажется неуклюжим, и я хотел бы его оптимизировать. У меня есть форма с несколькими элементами управления EditText. Некоторые из них открывают другой фрагмент, где пользователь выбирает материал и возвращается к основному фрагменту. Связь осуществлялась через интерфейсы, данные в связках и основной фрагмент, который повторно использовался через oFragment = (MainFragment) getSupportFragmentManager().findFragmentByTag(MainFragmentTag);
. Я использовал только модели представления для хранения и извлечения данных из баз данных. После того, как пользователь сделал свой выбор, я прочел текстовое содержимое элементов управления и сохранил его в новой записи POJO, которая была сохранена в базе данных.
Теперь я узнал об использовании Shared ViewModels для хранения временных данных и их распределения между фрагментами. Если вы можете выбирать элементы из списка, это действительно просто реализовать (из компонентов архитектуры Android):
public class SharedViewModel extends ViewModel {
private final MutableLiveData<Item> selected = new MutableLiveData<Item>();
public void select(Item item) {
selected.setValue(item);
}
public LiveData<Item> getSelected() {
return selected;
}
}
public class MasterFragment extends Fragment {
private SharedViewModel model;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
itemSelector.setOnClickListener(item -> {
model.select(item);
});
}
}
public class DetailFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
model.getSelected().observe(this, item -> {
// Update the UI.
});
}
}
Я думаю, что это можно использовать и для хранения данных TextEdit. Я бы чувствовал себя более комфортно, если бы данные пользовательского интерфейса хранились в моделях представления, вместо которых они читали пользовательские элементы управления во время процесса сохранения - из того, что я сейчас говорю о жизненных циклах Android, эти данные пользовательского интерфейса будут потеряны, если пользователь повернет экран. И я бы избавился от раздувного кода, чтобы использовать тот же экземпляр основного фрагмента.
Моя реализация использования Viewmodels для объединения данных EditText опубликована ниже и работает, но кажется довольно неуклюжей. Можете ли вы порекомендовать мне лучший способ сделать это? Или я сильно волнуюсь, и SavedInstanceState всегда будет хранить вещи, набранные пользователем в editTexts? Ниже мой код:
В основных фрагментах OnCreateView:
if (oStandardModel.getSelected().getValue() != null && !oStandardModel.getSelected().getValue().isEmpty()){
oBinding.EditNumber.setText(oStandardModel.getSelected().getValue());
}
oBinding.EditNumber.addTextChangedListener(new Manager.TextValidator(oBinding.EditNumber) {
@Override public void CacheIfValid(TextView textView, String text) {
if (text != null && !text.isEmpty() && Manager.isNumeric(text)){
oStandardModel.type(text.replaceAll(",", "."));
}
}
});
CacheifValid вдохновлен классом, который я украл у здесь . Он был предназначен для проверки текста, но я злоупотребляю им для хранения введенных пользователем данных (класс в служебном классе, называемом «менеджер»):
public static abstract class TextValidator implements TextWatcher {
private final TextView textView;
public TextValidator(TextView textView) {
this.textView = textView;
}
public abstract void CacheIfValid(TextView textView, String text);
@Override
final public void afterTextChanged(Editable s) {
String text = textView.getText().toString();
CacheIfValid(textView, text);
}
@Override
final public void beforeTextChanged(CharSequence s, int start, int count, int after) { /* Don't care */ }
@Override
final public void onTextChanged(CharSequence s, int start, int before, int count) { /* Don't care */ }
}
Соответствующие поля в классе ViewModel выглядят так:
private final MutableLiveData<String> selected = new MutableLiveData<String>();
public void type(String item) {
selected.setValue(item);
}
public MutableLiveData<String> getSelected() {
return selected;
}
Спасибо за чтение!