2013-07-27 1 views
1

Я пытаюсь создать графический интерфейс, который использует TabView на основе фрагментов. Код основан на FragmentSample, найденном в учебниках MvvmCross. Количество вкладок в TabView зависит от данных, читаемых из XML-файла, и на каждой вкладке используется один и тот же фрагмент. Пока все работает нормально. Проблемы начались, когда я попытался добавить в фрагмент полиморфный список. Код, используемый для создания полиморфного списка, в основном такой же, как и в примере коллекции (опять же из учебников MvvmCross).MvvmCross: Полиморфный список в виде вкладок на основе фрагмента

Сначала я попытался создать адаптер списка и назначить его MvxListView в Activity, связанном с TabView (класс, расширяющий MvxTabsFragmentActivity). В этом классе я переопределяю метод OnViewModelSet(). В пределах переопределения я создаю ListAdapter, который расширяет MvxAdapter и назначает его списку. Проблема в том, что метод GetBindableView (View conversionView, object dataContext, int templateId) в адаптере никогда не вызывается, поэтому все элементы в списке показаны вызовом метода ToString() для элементов, привязанных к списку. Может быть, стоит упомянуть, что если я определяю DataTemplate в файле .axml, список работает нормально - но не является полиморфным.

Затем я попытался переместить код, используемый для создания ListAdapter, в класс, связанный с фрагментом - тот, который получен из MvxFragment, что кажется лучше, поскольку список находится внутри фрагмента. Поскольку я не был уверен, какой метод переопределить, я сначала попробовал метод OnAttach, который дал исключение, говоря, что BindingContext не может быть использован в это время. Когда я поместил код в метод Resume() фрагмента, вещи наконец начали работать. Для экземпляра Context, необходимого при создании адаптера, я просто использовал base.Activity.

Итак, наконец, на мой вопрос. Описанное выше решение ОК - метод OnResume() - тот, который создает адаптер списка, или я должен использовать другой подход. Как я уже сказал, все работает нормально. Я просто не уверен, что это лучшее (хорошее) решение.

Надеюсь, что сообщение недолговечно - я старался быть как можно более кратким, не опуская важные детали. Любые советы будут оценены.

Урос

ответ

1

Я не думаю, что я полностью понял, что вы пытаетесь инициализирует где, ни которые ViewModels вы сопоставляя деятельность которых, фрагмент и список.

Однако в качестве основного ответа я обычно ожидаю, что вы создадите свой список и его адаптер в пределах OnCreateView создания фрагмента - это происходит после onAttach.

В источнике MVX, это где мы пытаемся создать BindingContext фрагмента - см https://github.com/slodge/MvvmCross/blob/v3/Cirrious/Cirrious.MvvmCross.Droid.Fragging/Fragments/MvxBindingFragmentAdapter.cs#L32

Я думаю, что вы может быть ОК с помощью OnResume - хотя вы можете обнаружить, это может вызываться несколько раз для данный созданный фрагмент - например вы будете вызваны, если текущая деятельность будет приостановлена, а затем возобновлена.Из-за этого я думаю, что вы, вероятно, будете более успешными, если вы решите переопределить OnCreateView

Существует довольно много проблем с жизненным циклом фрагментации - тем более, что он отличается от жизненного цикла работы (фрагменты могут и живут дольше, чем Мероприятия жить в)

документация по http://developer.android.com/guide/components/fragments.html хорошее начало - в том числе изображения:

Android Fragment lifecycle

+0

Надеюсь, этот ответ поможет - если это не так, попробуйте добавить немного примерного кода или, возможно, схему того, какие действия/фрагменты и ViewModels задействованы. Постараюсь помочь. – Stuart

1

Да, так же, как упомянуто Стюарт, то лучше сделать это в методе OnCreateView().

мне удалось сделать это так:

public override View OnCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{ 
    base.OnCreateView (inflater, container, savedInstanceState); 
    View fragmentView = this.BindingInflate(Resource.Layout.View_Applications, null); 
    var list = fragmentView.FindViewById<MvxListView>(Resource.Id.TheListView); 
    list.Adapter = new HeaderAdapter(Activity, (IMvxAndroidBindingContext) BindingContext); 
    return fragmentView; 
} 

Посмотрите Stuart's example with collections для получения более подробной информации.