我有一个活动,其中包含侧边栏导航和我的片段的占位符。(-> 单击侧边菜单时,我切换片段...)其中一个片段(称为 TabFragment)使用选项卡,其中填充有(列表)片段(类似于http://developer.android.com/reference/android/ support/v4/view/ViewPager.html示例,但我不使用操作栏选项卡,而是使用旧的)。
我第一次展示 TabFragment 时,一切正常。TabFragment 被调用,在那里我用我的 ListFragments(调用 onCreateView 等)“填充选项卡”(--> 就像在上面的示例中我实际上只是填充 viewpager)。有用。
然后我尝试将 TabFragment 的另一个实例放在屏幕上(我需要显示不同的列表并希望能够使用后退按钮 - > backstack),调用 TabFragment,我将片段添加到 TabsAdapter,但没有ListFragments 的生命周期方法被称为...为什么?
[我知道这不是最好的方法,有很多选项可以重写它以获得相同的效果,但由于它是第一次工作,我真的很想知道哪里出了问题]
活动代码
Fragment search1 = new MainListFr();
Bundle test1 = new Bundle();
test1.putInt(Constants.FRAGMENT_SEARCH_ID, 1);
g1.setArguments(test1);
m_fragmentTransaction = m_fragmentManager.beginTransaction();
m_fragmentTransaction.add(R.id.main_fragment_container, search1, "search1");
m_fragmentTransaction.addToBackStack("search1");
m_fragmentTransaction.commit();
m_layout.toggleSidebar();
MainListFr (=TabFragment)
public class MainListFr extends Fragment {
TabHost m_tabHost;
ViewPager m_viewPager;
TabsAdapter m_tabsAdapter;
@Override
public View onCreateView(final LayoutInflater inflater,
final ViewGroup container, final Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.stub_main, null);
m_tabHost = (TabHost) view.findViewById(android.R.id.tabhost);
m_tabHost.setup();
m_viewPager = (ViewPager) view.findViewById(R.id.main_pager);
m_tabsAdapter = new TabsAdapter(getActivity(), m_tabHost, m_viewPager);
View v1 = inflater.inflate(R.layout.tab_left, null);
View v2 = inflater.inflate(R.layout.tab_right, null);
Bundle args = getArguments();
m_tabsAdapter.addTab(m_tabHost.newTabSpec("topsearch").setIndicator(v1),
SearchListFr.class, args);
m_tabsAdapter.addTab(m_tabHost.newTabSpec("topsuggestion").setIndicator(v2),
SuggestionListFr.class, args);
if (savedInstanceState != null) {
m_tabHost.setCurrentTabByTag(savedInstanceState.getString("tab"));
}
return view;
}
}
SearchListFr (=ListFragment)
private ListView m_list = null;
private View m_progress = null;
private View m_noRes = null;
SearchAdapter m_searchAdapter = null;
private Vector<SearchItem> m_searchList = null;
private int m_searchId = 0;
@Override
public View onCreateView(final LayoutInflater inflater,
final ViewGroup container, final Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fr_videolist, null);
m_list = (ListView) view.findViewById(R.id.fr_videolist_list);
m_progress = view.findViewById(R.id.progress_root);
m_noRes = view.findViewById(R.id.noresult_root);
m_list.setVisibility(View.GONE);
m_noRes.setVisibility(View.GONE);
m_progress.setVisibility(View.VISIBLE);
Bundle args = getArguments();
if (args != null) {
m_searchId = args.getInt(Constants.FRAGMENT_SEARCH_ID);
}
// load the content here (asynctask)
new LoadSearchList().execute();
return view;
}
@Override
public void onActivityCreated(Bundle _savedInstanceState) {
super.onActivityCreated(_savedInstanceState);
m_searchAdapter = new SearchAdapter(getActivity());
m_list.setAdapter(m_searchAdapter);
m_list.setItemsCanFocus(true);
m_list.setOnItemClickListener(this);
}
选项卡适配器
/**
* This is a helper class that implements the management of tabs and all
* details of connecting a ViewPager with associated TabHost. It relies on a
* trick. Normally a tab host has a simple API for supplying a View or
* Intent that each tab will show. This is not sufficient for switching
* between pages. So instead we make the content part of the tab host
* 0dp high (it is not shown) and the TabsAdapter supplies its own dummy
* view to show as the tab content. It listens to changes in tabs, and takes
* care of switch to the correct paged in the ViewPager whenever the selected
* tab changes.
*/
public class TabsAdapter extends FragmentPagerAdapter
implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final TabHost mTabHost;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(String _tag, Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
static class DummyTabFactory implements TabHost.TabContentFactory {
private final Context mContext;
public DummyTabFactory(Context context) {
mContext = context;
}
@Override
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
public TabsAdapter(FragmentActivity activity, TabHost tabHost, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mTabHost = tabHost;
mViewPager = pager;
mTabHost.setOnTabChangedListener(this);
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
tabSpec.setContent(new DummyTabFactory(mContext));
String tag = tabSpec.getTag();
TabInfo info = new TabInfo(tag, clss, args);
mTabs.add(info);
mTabHost.addTab(tabSpec);
notifyDataSetChanged();
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
@Override
public void onTabChanged(String tabId) {
int position = mTabHost.getCurrentTab();
mViewPager.setCurrentItem(position);
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
// Unfortunately when TabHost changes the current tab, it kindly
// also takes care of putting focus on it when not in touch mode.
// The jerk.
// This hack tries to prevent this from pulling focus out of our
// ViewPager.
TabWidget widget = mTabHost.getTabWidget();
int oldFocusability = widget.getDescendantFocusability();
widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
mTabHost.setCurrentTab(position);
widget.setDescendantFocusability(oldFocusability);
}
@Override
public void onPageScrollStateChanged(int state) {
}
}