可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm working on android application that contains ViewPager
with Fragment
s, like this:
MainActivity
(MainActivityFragment
(screenSlideViewPager
(Fragment
s))), which means:
Activity
contains Fragment
contains ViewPager
contains Fragment
s
Now my problem is when rotate device or change screen rotation all Fragments in ViewPager are disappear.
any ideas to solve this issue?
EDIT 1
MainActivity.java:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getSupportFragmentManager().findFragmentByTag(TAG) == null) {
final FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
ft.add(android.R.id.content, new MainActivityFragment(), TAG);
ft.commit();
}
}
MainActivityFragment.java:
public class MainActivityFragment extends Fragment {
private ViewPager mPager = null;
private PagerAdapter mPageAdapter = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View reVal = inflater.inflate(R.layout.activity_main, container, false);
mPager = (ViewPager) reVal.findViewById(R.id.pagerMainContent);
mPageAdapter = new ScreenSlidePagerAdapter(getActivity().getFragmentManager());
mPager.setAdapter(mPageAdapter);
return reVal;
}
private MainGridViewFragment mainGridFragment;
private AlphabetGridViewFragment alphabetGridFragment;
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public android.app.Fragment getItem(int position) {
switch (position) {
case 1:
mainGridFragment = new MainGridViewFragment();
return mainGridFragment;
case 0:
alphabetGridFragment = new AlphabetGridViewFragment();
return alphabetGridFragment;
default:
return null;
}
}
@Override
public int getCount() {
return 2;
}
}
}
EDIT 2
Obviously MainActivity
and MainActivityFragment
are loaded, and the proof is The ActionBar
,
notice also that ViewPager
is loaded too, because you still can navigate between pages (the blue light means that the pager reached to last page) but you can't see its content.
回答1:
It looks like your main activity is using the getSupportFragmentManager() while your fragment is using getFragmentManager().
Not sure if this is worthy of an answer post but my rating is too low to reply any other way. :)
Edit: I believe you may also need to extend a FragmentActivity with the support library.
See: https://stackoverflow.com/a/10609839/2640693
Edit 2:
public class MainActivityFragment extends FragmentActivity {
private ViewPager mPager = null;
private PagerAdapter mPageAdapter = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View reVal = inflater.inflate(R.layout.activity_main, container, false);
mPager = (ViewPager) reVal.findViewById(R.id.pagerMainContent);
mPageAdapter = new ScreenSlidePagerAdapter(getChildFragmentManager());
mPager.setAdapter(mPageAdapter);
return reVal;
}
private MainGridViewFragment mainGridFragment;
private AlphabetGridViewFragment alphabetGridFragment;
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 1:
mainGridFragment = new MainGridViewFragment();
return (Fragment)mainGridFragment;
case 0:
alphabetGridFragment = new AlphabetGridViewFragment();
return (Fragment)alphabetGridFragment;
default:
return null;
}
}
@Override
public int getCount() {
return 2;
}
}
}
回答2:
I tried many solution but get success in any one. At last I fixed as below:
Use getActivity().getSupportFragmentManager() rather than getChildFragmentManager()
Override getItemId(int position) method in your ViewPagerAdapter class like below:
@Override
public long getItemId(int position) {
return System.currentTimeMillis();
}
For me it's working like charm, please also comment here your view.
回答3:
For the ones that are having problems with this you can try this:
private void InitializeUI(){
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setContentView(R.layout.activity_exame2);
InitializeUI();
}
i spent 2 days around this problem this was the only thing that worked for me, remeber to add android:configChanges="screenSize|orientation" to your activity in manifest
回答4:
Avoid creating the viewpager again. Put the code of onCreateView in onCreate(). And make your fragment use onRetainInstance(true). Hence this shall not recreate the fragment and again because the view is in the onCreate(), it will not be called again.
Check in the onCreateView() whether the view exists, if so then remove it.
Snippets:
//creates the view
private View createView(Bundle savedInstanceState) {
View view = getActivity().getLayoutInflater().inflate(your_layout, null, false);
//viewpager
return view;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//retains fragment instance across Activity re-creation
setRetainInstance(true);
viewRoot = createView(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (viewRoot != null && viewRoot.getParent() != null) {
ViewGroup parent = (ViewGroup) viewRoot.getParent();
parent.removeView(viewRoot);
Log.i("Test", "**************view.getParent(): " + viewRoot.getParent() + " " + viewRoot);
}
return viewRoot;
}
回答5:
You should rather use a getChildFragmentManager()
instead of the getFragmentManager()
.
You used
mPageAdapter = new ScreenSlidePagerAdapter(getActivity().getFragmentManager());
it should have been
mPageAdapter = new ScreenSlidePagerAdapter(getActivity().getChildFragmentManager());
in your fragment
回答6:
I had this exact same problem. It's tremendously confusing, but this thread helped me out except that the answers didn't really explain why it works.
The fix to this problem is to use Fragment.getChildFragmentManager()
. What's so confusing is the android API has Activity.getFragmentManager()
, but if you are trying to support older devices you need to use Activity.getSupportFragmentManager()
. However, this particular problem isn't about supporting older APIs.
The problem is that you have a Activity which has a Fragment which owns the ViewPager which owns several Fragments. You have Fragments within Fragments! The original design of Fragments didn't really handle this use case and later was updated to handle it. When you have Fragments within Fragments you need to use:
Fragment.getChildFragmentManager()
From within a Fragment
you have the choice of Fragment.getFragmentManager()
which returns the FragmentManager
of the Activity
vs Fragment.getChildFragmentManager()
which returns the FragmentManager
for this Fragment
which properly scopes the Fragment
s within your Fragment
.