我正在使用带有抽屉布局的活动,我需要在不同的碎片之间切换。其中一个片段正在使用带有FragmentStateViewPagerAdapter的ViewPager,我需要使用它来实现不同PreferenceFragments之间的Swipe Views行为。一切都工作正常:我启动应用程序,正确显示第一个片段(不使用ViewPager的片段)。即使使用滑动抽屉移动到第二个片段(ViewPager的一个)也可以。但是,如果我回到第一个Fragment并尝试再次打开第二个Fragment,我得到的只是一个空白屏幕!它仍然显示操作栏中的选项卡,并且ViewPager仍在工作,但片段只是...空白。此外,刷页面我可以注意到第二个片段仍然是空白,而第三个和后面的片段正确加载。在这样做之后,我还注意到向后滑动也会使两个不可见的页面正确加载。我没有得到例外,一切似乎都以正确的方式工作,除此之外。有没有人知道可能导致这个问题的原因是什么?我遵循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
答案 0 :(得分:3)
请尝试使用新的MyPageAdapter(get * Child * FragmentManager()
答案 1 :(得分:0)
user2884639的上述答案适用于我的情况,换句话说,当使用导航抽屉多次创建新实例时,getChildFragmentManager()是空白片段的解决方案。
与OP的不同之处在于我使用的是FragmentPagerAdapter,而不是FragmentStatePagerAdapter。我的代码如下所示:
托管ViewPager的片段:
package com.shemanigans.mime;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.astuetz.PagerSlidingTabStrip;
public class FragmentLongTermDCA extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
private MyAdapter adapterViewPager;
private ViewPager vpPager;
private PagerSlidingTabStrip tabs;
private OnPageChangeListener mPageChangeListener;
private static DCAfragment dcaFrag;
private static AnalysisFragment analysisFrag;
private static ActivityFragment activityFrag;
//private boolean freqSweepOn = false;
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static FragmentLongTermDCA newInstance(int sectionNumber) {
FragmentLongTermDCA fragment = new FragmentLongTermDCA();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public FragmentLongTermDCA() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_longterm_dca, container, false);
mPageChangeListener = new OnPageChangeListener() {
// This method will be invoked when a new page becomes selected.
@Override
public void onPageSelected(int position) {
switch(position) {
case 0:
break;
case 1:
/*dcaFrag.bioimpedancePlot.setVisibility(View.GONE);
dcaFrag.startButton.setVisibility(View.GONE);
dcaFrag.startButtonBar.setVisibility(View.GONE);*/
break;
case 2:
//analysisFrag.setupFragment(freqSweepOn);
break;
}
}
// This method will be invoked when the current page is scrolled
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// Code goes here
}
// Called when the scroll state changes:
// SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING, SCROLL_STATE_SETTLING
@Override
public void onPageScrollStateChanged(int state) {
// Code goes here
}
};
InitializeViewComponents(rootView);
return rootView;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((LongTerm) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
private void InitializeViewComponents(View rootView) {
vpPager = (ViewPager) rootView.findViewById(R.id.vpPager);
tabs = (PagerSlidingTabStrip) rootView.findViewById(R.id.tabs);
adapterViewPager = new MyAdapter(getChildFragmentManager()); // SOLTION TO PROBLEM
vpPager.setAdapter(adapterViewPager);
tabs.setViewPager(vpPager);
tabs.setOnPageChangeListener(mPageChangeListener);
tabs.setTextColor(getResources().getColor(R.color.appbasetheme_color));
tabs.setIndicatorColor(getResources().getColor(R.color.appbasetheme_color));
dcaFrag = DCAfragment.newInstance(4);
analysisFrag = AnalysisFragment.newInstance(4);
activityFrag = ActivityFragment.newInstance(4);
vpPager.setCurrentItem(1);
}
public static class MyAdapter extends FragmentPagerAdapter {
private static int NUM_ITEMS = 3;
public MyAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Returns total number of pages
@Override
public int getCount() {
return NUM_ITEMS;
}
// Returns the fragment to display for that page
@Override
public Fragment getItem(int position) {
switch (position) {
case 0: // Fragment # 0 - This will show FirstFragment different title
return activityFrag;
case 1: // Fragment # 0 - This will show FirstFragment
return dcaFrag;
case 2: // Fragment # 1 - This will show SecondFragment
return analysisFrag;
default:
return DCAfragment.newInstance(1);
}
}
// Returns the page title for the top indicator
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Activity";
case 1:
return "Raw Data";
case 2:
return "Analysis";
default:
return "Page " + position;
}
}
}
}
承载上述片段的托管活动内的OnNavigationDrawerItemSelected方法:
@Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by updating the fragment BioimpFragment
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
switch (position) {
// Depending on the item selected in the list, add unique tags / identifiers.
case 0:
fragmentTransaction
.replace(R.id.container, BioimpFragment.newInstance(position + 1), LIVE_DATA_TAG);
break;
case 1:
fragmentTransaction
.replace(R.id.container, BioimpFragment.newInstance(position + 1), PAST_HOUR_TAG);
break;
case 2:
fragmentTransaction
.replace(R.id.container, BioimpFragment.newInstance(position + 1), PAST_DAY_TAG);
break;
case 3:
fragmentTransaction
.replace(R.id.container, FragmentLongTermDCA.newInstance(position + 1), EXPORT_DATA_TAG);
break;
case 4:
fragmentTransaction
.replace(R.id.container, BioimpFragment.newInstance(position + 1), SCAN_TAG);
break;
}
fragmentTransaction.commit();
}