我在SupportV4 tabhost中的片段有问题,它在单个标签更改期间加载了两个片段。 (使用Tabhost; android / support / v4 / app / FragmentTabHost)
问题发生是因为我想使用MVVMCross及其ViewModel,所以我需要在Fragments中加载ViewModels(在选项卡内)。
为了清理,我使用了以下流程; - 加载ActionActivity,然后加载Fragment以保存Tabs - AddTabs(片段内) - 使用SupportFragmentManager
添加Fragment的每个TabChange开关包含标签的My Fragment具有以下内容:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
var ignored = base.OnCreateView(inflater, container, savedInstanceState);
var rootView = this.BindingInflate(LayoutId, null);
activityTabHost = (FragmentTabHost) rootView.FindViewById(Android.Resource.Id.TabHost);
activityTabHost.Setup(Activity, ChildFragmentManager, Resource.Id.realtabcontent);
var savedcurrentTabTag = string.Empty;
AddTabs(savedInstanceState);
if (savedInstanceState != null) {
savedcurrentTabTag = savedInstanceState.GetString(SavedTabIndexStateKey);
activityTabHost.SetCurrentTabByTag(savedcurrentTabTag);
}
if (lookup.Any()) {
OnTabChanged(string.IsNullOrWhiteSpace(savedcurrentTabTag) ? lookup.First().Key : savedcurrentTabTag);
}
activityTabHost.SetOnTabChangedListener(this);
return rootView;
}
TabLoading(逐个)
private static void AddTab(Fragment fragment, // Check incomming (was MvxTabsFragmentActivity)
TabHost tabHost,
Android.Widget.TabHost.TabSpec tabSpec,
MvxTabFragmentInfo tabInfo) {
// Attach a Tab view factory to the spec
tabSpec.SetContent(new MvxTabFragmentFactory(fragment.Activity));
var tag = tabSpec.Tag;
// Check to see if we already have a CachedFragment for this tab, probably
// from a previously saved state. If so, deactivate it, because our
// initial state is that a tab isn't shown.
tabInfo.CachedFragment = fragment.ChildFragmentManager.FindFragmentByTag(tag);
if (tabInfo.CachedFragment != null && !tabInfo.CachedFragment.IsDetached) {
var ft = fragment.ChildFragmentManager.BeginTransaction();
ft.Detach(tabInfo.CachedFragment);
ft.Commit();
fragment.ChildFragmentManager.ExecutePendingTransactions();
}
tabHost.AddTab(tabSpec, Class.FromType(tabInfo.FragmentType), tabInfo.Bundle);
}
标签更改:
public virtual void OnTabChanged(string tag) {
var newTab = lookup[tag];
if (currentTab != newTab) {
var ft = ChildFragmentManager.BeginTransaction();
OnTabFragmentChanging(tag, ft);
if (currentTab != null) {
if (currentTab.CachedFragment != null) {
ft.Detach(currentTab.CachedFragment);
}
}
if (newTab != null) {
if (newTab.CachedFragment == null) {
// CAUTION!!!
// This adds a NEW fragment to the ChildFragmentManager, but the TabHost creates its own Fragment to!
// (that one needs to be cancled, regocnized by the lack of a ViewModel)
newTab.CachedFragment = Instantiate(Activity, FragmentJavaName(newTab.FragmentType), newTab.Bundle);
FixupDataContext(newTab);
ft.Add(TabContentId, newTab.CachedFragment, newTab.Tag);
} else {
FixupDataContext(newTab);
ft.Attach(newTab.CachedFragment);
}
}
currentTab = newTab;
currentTabTag = (newTab != null) ? newTab.Tag : string.Empty;
ft.Commit();
ChildFragmentManager.ExecutePendingTransactions();
}
TabHost.ViewTreeObserver.RemoveOnTouchModeChangeListener(TabHost);
}
如您所见,我目前正在加载自己的Fragment,然后将ViewModel附加到Fragment。很高兴说ViewModel已经存在,它来自一个包含4个ViewModel的父ViewModel,每个Tab都有一个。
BUT! TabHost在TabChange期间创建了自己的Fragment,但没有ViewModel,因为它没有自动加载到MvxFragment中。
这是我的解决方法,取消了没有ViewModel的Fragment (否则我会在彼此之上找到碎片)。
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (ViewModel == null) {
return null;
}
base.OnCreateView(inflater, container, savedInstanceState);
return this.BindingInflate(Resource.Layout.GroupedFragmentView, null);
}
这是一个解决方法,我希望能够更多地控制创建片段的Tabhost。
有谁知道如何进入SupportV4 tabhost来控制片段创建?或者其他任何人都有一个很好的解决方案,而不是我的解决方法?
答案 0 :(得分:1)
答案是解决方法; (但更好的解决方案是Cheesebaron的建议)
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
if (ViewModel == null)
{
return null;
}
base.OnCreateView(inflater, container, savedInstanceState);
return this.BindingInflate(Resource.Layout.GroupedFragmentView, null);
}