我正在尝试创建一个包含两个标签的活动,一个标注FragmentA
,一个标记FragmentB
。以下是我将片段添加到Activity:
[Activity(Label = "My App")]
public class MyActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.ConnectionMenu);
ActionBar.NavigationMode = ActionBarNavigationMode.Tabs;
AddTab("A", new FragmentA());
AddTab("B", new FragmentB());
}
private void AddTab(string tabText, Fragment fragment)
{
var tab = ActionBar.NewTab();
tab.SetText(tabText);
tab.TabSelected += (sender, e) =>
{
e.FragmentTransaction.Replace(
Resource.Id.fragmentContainer,
fragment);
};
ActionBar.AddTab(tab);
}
}
当我旋转方向时,我想保持片段中的字段填充相同。我将数据保存在OnSaveInstanceState
中并恢复OnActivityCreated
中的数据。但是,我注意到每个旋转调用OnCreateView
和OnActivityCreated
方法两次。第一次包含我填写的Bundle
,第二次包含的是null。
我认为我的错误出现在MyActivity
课程中,但如果您需要更多信息,请告诉我们!
答案 0 :(得分:1)
鉴于您在Activity.OnCreate()
中创建了片段,您将始终有2次调用,因为在方法中创建了新的调用,并在base.OnCreate()
中维护旧调用。您应该做的不是始终创建这些片段,而是可以通过标签或ID搜索现有片段,而是使用选项卡中的片段。
即
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.ConnectionMenu);
ActionBar.NavigationMode = ActionBarNavigationMode.Tabs;
if(savedInstanceState == null)
{
AddTab("A", new FragmentA());
AddTab("B", new FragmentB());
}
else
{
Fragment a = (FragmentA)SupportFragmentManager.FindFragmentByTag("my_tag_a");
Fragment b = (FragmentB)SupportFragmentManager.FindFragmentByTag("my_tag_b");
AddTab("A", a);
AddTab("B", b);
}
}
答案 1 :(得分:0)
我最终解决了这个问题。正如@JonDouglas所说,在创建新片段之前,您需要确保选项卡尚未加载。为此,可以使用标记从FragmentManager
类加载片段。在TabSelected
事件期间,如果先前未创建片段,则会创建一个新片段并使用该标记将其添加到事件FragmentTransaction
。在TabUnselected
事件期间,如果片段已创建,则它将被分离。
我还添加了Bundle
值以保留最后一个活动标签。
以下是我用来解决问题的代码。
[Activity(Label = "My App")]
public class MyActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.ConnectionMenu);
ActionBar.NavigationMode = ActionBarNavigationMode.Tabs;
AddTab("A", "a_fragment", () => new FragmentA());
AddTab("B", "b_fragment", () => new FragmentB());
if (savedInstanceState != null)
{
var selectedTab = savedInstanceState.GetInt(
"ActionBar.SelectedNavigationIndex", 0);
ActionBar.SetSelectedNavigationItem(selectedTab);
}
}
protected override void OnSaveInstanceState(Bundle savedInstanceState)
{
base.OnSaveInstanceState(savedInstanceState);
savedInstanceState.PutInt(
"ActionBar.SelectedNavigationIndex",
ActionBar.SelectedNavigationIndex);
}
private void AddTab<TFragment>(
string tabText,
string tag,
Func<TFragment> ctor) where TFragment : Fragment
{
var tab = ActionBar.NewTab();
tab.SetText(tabText);
tab.SetTag(tag);
var fragment = FragmentManager.FindFragmentByTag<TFragment>(tag);
tab.TabSelected += (sender, e) =>
{
if (fragment == null)
{
fragment = ctor.Invoke();
e.FragmentTransaction.Add(
Resource.Id.fragmentContainer,
fragment,
tag);
}
else
{
e.FragmentTransaction.Attach(fragment);
}
};
tab.TabUnselected += (sender, e) =>
{
if (fragment != null)
{
e.FragmentTransaction.Detach(fragment);
}
};
ActionBar.AddTab(tab);
}
}