Если нет чистого решения, что не так с моим подходом к архитектуре? Должен ли я использовать фрагменты для такого сценария?
Да, фрагменты - правильный выбор
Резюме:
- Нет реальной альтернативы связыванию
Views
с LiveData
.
- При использовании
LiveData
требуется LifeCycle
.
- Если жизненный цикл подпредставлений в последовательности должен быть короче, чем жизненный цикл активности, тогда лучше использовать фрагменты.
Подробности
Нет реальной альтернативы связыванию Views
с LiveData
.
Модели представлений не должны содержать незавершенные ссылки на представления, иначе представления существуют до тех пор, пока существует модель представления, вызывающая утечку памяти. Есть три шаблона наблюдателя, чтобы обсудить, как представления могут наблюдать за моделями представлений.
а.) Изменяемые живые данные
Они требуют жизненного цикла. Ссылки очищаются автоматически, когда заканчивается жизненный цикл. Это рекомендуемое решение.
б.) Слабые ссылки
Теоретически это должно работать. Слабая ссылка должна быть очищена сборщиком мусора, когда исчезнет последняя жесткая ссылка на представление. На практике решение нестабильно и ссылки иногда уходят преждевременно.
c.) Самодельный наблюдатель
Созданный вручную наблюдатель должен вызывать метод удаления. К сожалению, нет определенного хука уничтожения, когда представление исчезает. В представлении нет места для вызова метода удаления.
В результате а.) является единственным возможным решением согласно моему опыту.
Поскольку для LiveData требуется жизненный цикл, лучше всего использовать фрагменты.
Упомянутые здесь подвиды создаются последовательно. Если мы привяжем их к активности, они будут накапливаться до тех пор, пока активность не исчезнет, хотя они нужны только в течение небольшого промежутка времени в последовательности.
Фрагменты могут существовать в течение части времени действия. Это правильное решение для привязки к ним подвидов последовательности.
Пример кода
Викторины здесь называются вызовами. FragmentManger
всегда относится к действию, а LifecycleOwner
— либо к действию, либо к фрагменту.
# A view model acceptor interface for views
public interface ViewModelAcceptor<T extends ViewModel> {
void plugViewModel(
T viewModel,
LifecycleOwner lifecycleOwner,
FragmentManager fragmentManager
);
}
# In the parent view class of the challenges new challenges are created
# in sequence
ChallengeFragment challengeFragment = new ChallengeFragment();
challengeFragment.setChallengeViewModel(challengeViewModel);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(this.getId(), challengeFragment);
fragmentTransaction.commit();
# ChallengeFragment
public class ChallengeFragment extends Fragment {
private ChallengeViewModel challengeViewModel;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
return new ChallengeView(getActivity(), null);
}
public void setChallengeViewModel(ChallengeViewModel challengeViewModel) {
this.challengeViewModel = challengeViewModel;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ChallengeView challengeView = (ChallengeView) getView();
Objects.requireNonNull(challengeView)
.plugViewModel(challengeViewModel, this, getFragmentManager());
}
}
# Challenge views are the child views of the sequence
public class ChallengeView extends ConstraintLayout implements ViewModelAcceptor<ChallengeViewModel> {
[...]
}
person
Blcknx
schedule
26.04.2018
new ViewModelProvider
? - person pskink   schedule 18.04.2018ViewModel
была привязана к вашему мастеруViewModel
, верно? - person pskink   schedule 18.04.2018ViewModel
. - person Blcknx   schedule 18.04.2018How to generate view models from inside a view model?
так что я не понимаю, что вам действительно нужно - person pskink   schedule 18.04.2018