我有一个ViewPager
托管在Fragment
内。作为测试,我用相同的类为如下的三个片段初始化:ViewPager child片段空
mAdapter = new GenericFragmentPagerAdapter(ChildFragmentManager);
mAdapter.Add(frag1);
mAdapter.Add(frag2);
mAdapter.Add(frag3);
mViewPager = Activity.FindViewById<ViewPager>(Resource.Id.fragment_navigation_viewpager);
mViewPager.Adapter = mAdapter;
mTabLayout = Activity.FindViewById<TabLayout>(Resource.Id.tab_layout);
mTabLayout.SetupWithViewPager(mViewPager);
由于我Fragment
对象将被动态添加到ViewPager
,我GenericFragmentPagerAdapter
延伸FragmentStatePagerAdapter
。
的Fragment
举办ViewPager
是我Activity
承载一个NavigationView
如下内实例:
NavigationFragment fragment = NavigationFragment.NewInstance();
SupportFragmentManager.BeginTransaction().
Replace(Resource.Id.activity_main_content_container,fragment).
Commit();
我的问题是:这三个片段正确添加到ViewPager
,但和frag3
显示为空,而frag2
正确显示内容。运行调试器和frag3
确实得到了正确的实例化,所以我不明白为什么它们应该显示为空。
显然,使用嵌套片段时,适配器应该使用getChildFragmentManager()
进行初始化。可悲的是,我仍然使用getSupportFragmentManager()
的效果。
我错过了什么,或者有没有办法调试这个问题?
编辑
我设法让正在发生的问题的一个更好的主意。由于某些原因,如果我的片段延伸ListFragment
ViewPager
得到正确加载并显示其子。但是,如果我使用正常Fragment
那么问题就会发生。老实说,我不知道为什么,所以我提供了下面的代码,以防有人想尝试。
MainAcitivty.cs
namespace App
{
[Activity(Label = "TestActivity", Theme = "@style/FM360MaterialTheme",
ConfigurationChanges = Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.ScreenSize)]
public class TestActivity : FragmentActivity
{
TabLayout mTabLayout;
ViewPager mViewPager;
GenericFragmentPagerAdapter mAdapter;
static FMNavigation mFMNavigation;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your application here
// Set our view from the "startup" layout resource
SetContentView(Resource.Layout.fragment_navigation);
InitializeNavigation();
}
private void InitializeNavigation()
{
ProgressDialog progressDialog = ProgressDialog.Show(
this,
GetString(Resource.String.Initializing),
GetString(Resource.String.one_moment)
);
new Thread(new ThreadStart(delegate {
// Here the mFMNavigation variable is initialized
// because it required downloaded data from the internet.
RunOnUiThread(() =>
{
progressDialog.Dismiss();
// If no error occured, initialize UI components.
InitializeUserInterface();
});
})).Start();
}
private void InitializeUserInterface()
{
string fragmentTitle = "Test Fragment Title";
// Items that will be inserted inside the adapter.
var datasource = mFMNavigation.CurrentItem.Datasource;
NavigationListFragment f1 = NavigationListFragment.NewInstance(
datasource,
mFMNavigation,
"Title 1");
NavigationListFragment f2 = NavigationListFragment.NewInstance(
datasource,
mFMNavigation,
"Title 2");
mAdapter = new GenericFragmentPagerAdapter(SupportFragmentManager);
mAdapter.Add(f1);
mAdapter.Add(f2);
mViewPager = FindViewById<ViewPager>(Resource.Id.fragment_navigation_viewpager);
mViewPager.Adapter = mAdapter;
mTabLayout = FindViewById<TabLayout>(Resource.Id.tab_layout);
mTabLayout.SetupWithViewPager(mViewPager);
}
}
}
GenericFragmentPagerAdapter.cs
using Android.Support.V4.App;
using System.Collections.Generic;
namespace Adapters
{
public class GenericFragmentPagerAdapter : FragmentStatePagerAdapter
{
private List<Fragment> mFragments;
public GenericFragmentPagerAdapter (FragmentManager fm) : base(fm)
{
mFragments = new List<Fragment>();
}
public void Add(Fragment fragment)
{
if (!mFragments.Contains (fragment))
mFragments.Add (fragment);
}
public void Remove(Fragment fragment)
{
if (mFragments.Contains (fragment))
mFragments.Remove (fragment);
}
public void RemoveAt(int position)
{
if (mFragments.Count <= position)
return;
mFragments.RemoveAt(position);
}
public void RemoveUntil(int position)
{
position++;
while (mFragments.Count > position)
mFragments.RemoveAt(position);
}
public override int Count { get { return mFragments.Count; }}
public override Fragment GetItem(int position) { return mFragments [position]; }
public override int GetItemPosition(Java.Lang.Object item) { return PositionNone; }
public override Java.Lang.ICharSequence GetPageTitleFormatted(int position)
{
Fragment f = mFragments[position];
if (f is NavigationListFragment)
{
NavigationListFragment listFragment = (NavigationListFragment)f;
return new Java.Lang.String(listFragment.FragmentTitle);
}
return new Java.Lang.String("");
}
}
}
NavigationListFragment.cs
namespace App.Fragments
{
public class NavigationListFragment : Fragment
{
List<FMNavigationListItem> mDatasource;
FMNavigation mFMNavigation;
string mFragmentTitle;
ExpandableListviewAdapter mAdapter;
public NavigationListFragment()
{
}
public static NavigationListFragment NewInstance(List<FMNavigationListItem> items, FMNavigation navigation, string fragmentTitle)
{
NavigationListFragment f = new NavigationListFragment();
f.mFMNavigation = navigation;
f.mDatasource = items;
f.mFragmentTitle = fragmentTitle;
return f;
}
public override void OnActivityCreated(Bundle savedInstanceState)
{
base.OnActivityCreated(savedInstanceState);
RetainInstance = true;
InitializeListView();
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.Inflate(
Resource.Layout.fragment_navigation_list,
container,
false);
}
/// <summary>
///
/// </summary>
void InitializeListView()
{
ExpandableListView listView = Activity.FindViewById<ExpandableListView>(
Resource.Id.fragment_navigation_list_expandable_listview);
// "Remove" listview and set empty state.
if (mDatasource == null || mDatasource.Count <= 0)
{
TextView emptyView = Activity.FindViewById<TextView>(
Resource.Id.fragment_navigation_list_empty_textview);
emptyView.Text = GetString(Resource.String.empty_list_text);
listView.Visibility = ViewStates.Gone;
return;
}
// Here we build a list of groupable items based on the
// data source given.
List<ExpandableItem> groupItems = new List<ExpandableItem>();
foreach (var dataItem in mDatasource)
{
string className = mFMNavigation.NameOfClassId(dataItem.ClassId);
// Attempt to find the group that has the same class name.
// If it exists add the data item to the group. Otherwise
// create a new group and add the item.
ExpandableItem groupItem = groupItems.Find(x => x.GroupTitle.Equals(className));
if (groupItem == null)
{
ExpandableItem item = new ExpandableItem();
item.GroupTitle = className;
item.ChildItems = new List<FMNavigationListItem>();
item.ChildItems.Add(dataItem);
groupItems.Add(item);
continue;
}
groupItem.ChildItems.Add(dataItem);
}
mAdapter = new ExpandableListviewAdapter(Activity, groupItems);
listView.SetAdapter(mAdapter);
}
#region Fragment Properties
public string FragmentTitle
{
get { return mFragmentTitle; }
}
#endregion
}
}
ExpandableListviewAdapter.cs
namespace App.Adapters
{
class ExpandableListviewAdapter : BaseExpandableListAdapter
{
private Activity mContext;
private List<ExpandableItem> mDataItems;
public ExpandableListviewAdapter(Activity context, List<ExpandableItem> items)
: base()
{
mContext = context;
mDataItems = items;
// Sort the groups and all of its child elements alphabetically.
SortDataItems();
}
void SortDataItems()
{
// Sort each group alphabetically.
mDataItems.Sort(delegate (ExpandableItem e1, ExpandableItem e2)
{
return e1.GroupTitle.CompareTo(e2.GroupTitle);
});
// Iterate over each group of items and sort the
// children alphabetically.
foreach (var d in mDataItems)
{
d.ChildItems.Sort(delegate (FMNavigationListItem i1, FMNavigationListItem i2)
{
return i1.DisplayAttributes[0].CompareTo(i2.DisplayAttributes[0]);
});
}
}
public override View GetChildView(int groupPosition, int childPosition, bool isLastChild, View convertView, ViewGroup parent)
{
if (convertView == null)
convertView = mContext.LayoutInflater.Inflate(Resource.Layout.adapter_expandable_listview_listitem, null);
FMNavigationListItem item = mDataItems[groupPosition].ChildItems[childPosition];
convertView.FindViewById<TextView>(Resource.Id.adapter_expandable_listview_listitem_textview1).Text = item.DisplayAttributes[0];
convertView.FindViewById<TextView>(Resource.Id.adapter_expandable_listview_listitem_textview2).Text = item.DisplayAttributes[1];
convertView.FindViewById<TextView>(Resource.Id.adapter_expandable_listview_listitem_textview3).Text = item.DisplayAttributes[2];
ImageButton i = convertView.FindViewById<ImageButton>(Resource.Id.adapter_expandable_listview_listitem_overflow_button);
i.Click += OverflowButtonClicked;
return convertView;
}
private void OverflowButtonClicked(object sender, EventArgs e)
{
Toast.MakeText(
mContext,
"Overflow button clicked!",
ToastLength.Short).Show();
}
public override View GetGroupView(int groupPosition, bool isExpanded, View convertView, ViewGroup parent)
{
if (convertView == null)
convertView = mContext.LayoutInflater.Inflate(Resource.Layout.adapter_expandable_listview_header, null);
// We expand all child objects from the group per default.
// Normal default ist that all children are collapsed.
ExpandableListView listView = (ExpandableListView)parent;
listView.ExpandGroup(groupPosition);
// Set the header title to be the group title.
ExpandableItem item = mDataItems[groupPosition];
convertView.FindViewById<TextView>(Resource.Id.adapter_expandable_listview_header_textview).Text = item.GroupTitle;
return convertView;
}
public override int GroupCount
{
get
{
return mDataItems.Count;
}
}
public override bool HasStableIds
{
get
{
return true;
}
}
public override Java.Lang.Object GetChild(int groupPosition, int childPosition)
{
throw new NotImplementedException();
}
public override long GetChildId(int groupPosition, int childPosition)
{
return childPosition;
}
public override int GetChildrenCount(int groupPosition)
{
return mDataItems[groupPosition].ChildItems.Count;
}
public override bool IsChildSelectable(int groupPosition, int childPosition)
{
return true;
}
public override Java.Lang.Object GetGroup(int groupPosition)
{
throw new NotImplementedException();
}
public override long GetGroupId(int groupPosition)
{
return groupPosition;
}
public FMNavigationListItem ChildAt(int groupPosition, int childPosition)
{
return mDataItems[groupPosition].ChildItems[childPosition];
}
}
/// <summary>
///
/// </summary>
internal class ExpandableItem
{
public string GroupTitle;
public List<FMNavigationListItem> ChildItems;
}
}
能否请你分享,可以重现该问题一个基本的演示? –
我仍在试验和尝试一些事情。如果事情变得更清楚,我会让你知道的。 – Ivan
@ ElvisXia-MSFT我可以提供一个测试项目解决方案,还是应该发布重现错误的代码? – Ivan