我正在使用带有抽屉布局的活动,我需要在不同的片段之间切换。这些片段之一是使用带有 FragmentStateViewPagerAdapter 的 ViewPager,我需要使用它来实现不同 PreferenceFragment 之间的滑动视图行为。一开始一切正常:我启动应用程序,第一个片段正确显示(不使用 ViewPager 的片段)。即使使用滑动抽屉移动到第二个片段(ViewPager 的片段)也可以。但是,如果我回到第一个 Fragment 并尝试再次打开第二个 Fragment,我得到的只是一个空白屏幕!它仍然在操作栏中显示选项卡,并且 ViewPager 仍在工作,但片段只是......空白。此外,滑动页面我可以注意到第二个 Fragment 仍然是空白的,而第三个和以下的正确加载。这样做之后,我还注意到向后滑动也会使两个不可见的页面正确加载。我没有得到任何异常,除此之外,一切似乎都以正确的方式工作。有谁知道可能导致此问题的原因?我遵循了 Android 开发者教程,包括 DrawerLayout 和 ViewPager。
这是我的代码:
主要活动:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
homeFragment = new HomeFragment();
swypeFragment = new SwypeTabsPreferences();
mTitle = mDrawerTitle = getTitle();
mSections = getResources().getStringArray(R.array.sections_array);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
//set a custom shadow that overlays the main content when the drawer opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
//set up the drawer's list view with items and click listener
mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item,
mSections));
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
//Enable ActionBar app icon to behave as action to toggle nav drawer
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
//ActionBarDrawerToggle ties together the proper interactions between
//the sliding drawer and the action bar app icon
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host activity */
mDrawerLayout, /* DrawerLayout Object */
R.drawable.ic_drawer, /* nav Drawer image to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_close /* "close drawer description for accessibility */
) {
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
invalidateOptionsMenu(); //creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); //Creates call to onPrepareOptionsMenu()
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
if (savedInstanceState == null) {
selectItem(0);
}
}
public void onDestroy() {
super.onDestroy();
Log.d("DEBUG", "In Method: onDestroy()");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
/*Called whenever we call invalidateOptionsMenu() */
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
//If the nav drawer is open, hide action items related to the content view
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
//The action bar home/up action open or close the drawer.
//ActionBarDrawerToggle will take care of this.
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onResume() {
super.onResume();
}
private class DrawerItemClickListener implements ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
// Swaps fragments in the main content view
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void selectItem(int position) {
//update the main content by replacing fragments
if (position == 0) {
//Fragment fragment = new HomeFragment();
//fragment.setRetainInstance(true);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction trans = fragmentManager.beginTransaction();
if (null ==fragmentManager.findFragmentByTag("home")) {
trans.replace(R.id.content_frame, homeFragment, "home");
}
trans.commit();
//update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(mSections[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
else if (position == 1) {
//Fragment fragment = new SwypeTabsPreferences();
//fragment.setRetainInstance(true);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction trans = fragmentManager.beginTransaction();
if (null ==fragmentManager.findFragmentByTag("swype")) {
trans.replace(R.id.content_frame, swypeFragment, "swype");
}
trans.commit();
//update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(mSections[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
else if (position == 2) {
//TO BE DONE
}
}
@Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
/**
* When using the ActionBarDrawerToggle, you must call it during onPostCreate()
* and onConfigurationChanged()
*/
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
//Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
//Pass any configuration change to the drawer toggle
mDrawerToggle.onConfigurationChanged(newConfig);
}
}
使用 ViewPager 的片段:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.context = getActivity();
this.setRetainInstance(true);
//pager.setOffscreenPageLimit(6);
//Specify that the Home/up button should not be enabled, since there is no hierarchical parent
//actionBar.setHomeButtonEnabled(true)
}
@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
//When the given tab is selected, switch to the corresponding page in the ViewPager
pager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
/*private class MyPageAdapter extends FragmentStatePagerAdapter {
private final String[] TITLES = context.getResources().getStringArray(R.array.settings_titles);
private ArrayList<Fragment> fragments;
public MyPageAdapter(FragmentManager fm, ArrayList<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
@Override
public int getCount() {
return this.fragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return TITLES[position % NUM_ITEMS] ;
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}*/
public abstract class MyPageAdapter extends FragmentStatePagerAdapter {
private SparseArray<WeakReference<Fragment>> mPageReferenceMap = new SparseArray<WeakReference<Fragment>>(0);
private List<String> mTabTitles;
public abstract Fragment initFragment(int position);
public MyPageAdapter(FragmentManager fm, List<String> tabTitles) {
super(fm);
mTabTitles = tabTitles;
}
@Override
public Object instantiateItem(ViewGroup viewGroup, int position) {
mPageReferenceMap.put(Integer.valueOf(position), new WeakReference<Fragment>(initFragment(position)));
return super.instantiateItem(viewGroup, position);
}
@Override
public int getCount() {
return mTabTitles.size();
}
@Override
public CharSequence getPageTitle(int position) {
return mTabTitles.get(position);
}
@Override
public void startUpdate(ViewGroup container) {}
@Override
public Fragment getItem(int pos) {
Fragment f;
switch (pos) {
case 0:
f = new FirstPreferencesFragment();
mPageReferenceMap.put(pos, new WeakReference<Fragment>(f));
return f;
case 1:
f = new SecondPreferencesFragment();
mPageReferenceMap.put(pos, new WeakReference<Fragment>(f));
return f;
case 2:
f = new ThirdPreferencesFragment();
mPageReferenceMap.put(pos, new WeakReference<Fragment>(f));
return f;
case 3:
f = new FourthPreferencesFragment();
mPageReferenceMap.put(pos, new WeakReference<Fragment>(f));
return f;
case 4:
f = new FifthPreferencesFragment();
mPageReferenceMap.put(pos, new WeakReference<Fragment>(f));
return f;
case 5:
f = new SixthPreferencesFragment();
mPageReferenceMap.put(pos, new WeakReference<Fragment>(f));
return f;
case 6:
f = new SeventhPreferencesFragment();
mPageReferenceMap.put(pos, new WeakReference<Fragment>(f));
return f;
default:
return null;
}
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
mPageReferenceMap.remove(position);
}
public Fragment getFragment(int key) {
WeakReference<Fragment> weakReference = mPageReferenceMap.get(key);
if (null != weakReference) {
return (Fragment) weakReference.get();
}
else {
return null;
}
}
@Override
public int getItemPosition(Object object) {
if (object instanceof FirstPreferencesFragment) {
return 0;
}
else if (object instanceof SecondPreferencesFragment) {
return 1;
}
else if (object instanceof ThirdPreferencesFragment) {
return 2;
}
else if (object instanceof FourthPreferencesFragment) {
return 3;
}
else if (object instanceof FifthPreferencesFragment) {
return 4;
}
else if (object instanceof SixthPreferencesFragment) {
return 5;
}
else if (object instanceof SeventhModePreferencesFragment) {
return 6;
}
else
return POSITION_NONE;
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.pager_layout, container, false);
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState == null) {
//this.mPagerTitleStrip = (PagerTitleStrip) getActivity().findViewById(R.id.pager_title_strip);
actionBar = getActivity().getActionBar();
pager = (ViewPager) getActivity().findViewById(R.id.viewpager);
setAdapter();
pager.setAdapter(pageAdapter);
}
else {
int index = pager.getCurrentItem();
MyPageAdapter adapter = ((MyPageAdapter) pager.getAdapter());
Fragment f = adapter.getFragment(index);
getFragmentManager().beginTransaction().replace(pager.getId(), f).commit();
}
//Specify that tabs should be displayed in the action bar.
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
pager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
//When swiping between different app sections, select the corresponding tab.
//We can also use ActionBar.Tab#select() to do this if we have a reference to the tab
actionBar.setSelectedNavigationItem(position);
}
});
//For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < pageAdapter.getCount(); i++) {
//Create a tab with text corresponding to the page title defined by the adapter.
//Also specify this activity object, which implements the TabListener interface, as the listener for when this tab is selected.
actionBar.addTab(actionBar.newTab().setText(pageAdapter.getPageTitle(i)).setTabListener(this));
}
}
@Override
public void onPause() {
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
super.onPause();
}
private void setAdapter() {
if (pageAdapter == null)
pageAdapter = new MyPageAdapter(getFragmentManager(), Arrays.asList(context.getResources().getStringArray(R.array.settings_titles))) {
@Override
public Fragment initFragment(int position) {
Fragment fragment;
if (position == 0) {
fragment = Fragment.instantiate(getActivity(), FirstPreferencesFragment.class.getName());
}
else if (position == 1) {
fragment = Fragment.instantiate(getActivity(), SecondPreferencesFragment.class.getName());
}
else if (position == 2) {
fragment = Fragment.instantiate(context, ThirdPreferencesFragment.class.getName());
}
else if (position == 3) {
fragment = Fragment.instantiate(context, FourthPreferencesFragment.class.getName());
}
else if (position == 4) {
fragment = Fragment.instantiate(context, FifthPreferencesFragment.class.getName());
}
else if (position == 5) {
fragment = Fragment.instantiate(context, SixthPreferencesFragment.class.getName());
}
else if (position == 6) {
fragment = Fragment.instantiate(context, SeventhPreferencesFragment.class.getName());
}
else
fragment = null;
return fragment;
}
};
Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
pager.setVisibility(View.VISIBLE);
//mPagerTitleStrip.setVisibility(View.VISIBLE);
pageAdapter.notifyDataSetChanged();
}
});
}
我在用着:
android.support.v4.app.ViewPager,
android.support.v13.app.FragmentStatePagerAdapter