I have a main activity called GuivActivity that uses viewPager to switch between two fragments (listFragment and SearchFragment). But when I try to get Fragment by id inside onPageSelected, it returns null.
All I want to do here is to restart the loader in ListFragment so that every time when I come back I will have most updated data.
in GuivActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_guiv);
viewPager = (ViewPager)findViewById(R.id.viewpager);
indicator = (TitlePageIndicator) findViewById(R.id.titleindicator);
pagerAdapter = new PagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
indicator.setViewPager(viewPager);
indicator.setOnPageChangeListener(listener);
}
ViewPager.OnPageChangeListener listener = new ViewPager.SimpleOnPageChangeListener(){
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
switch (position){
case 0:
FragmentManager fm = getSupportFragmentManager();
ListFragment listFragment = (ListFragment) fm.findFragmentById(R.id.list_fragment_id);
case 1:
default:
break;
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
};
in ListFragment.java
@Override
public void onResume() {
Message.message(mContext,"on resumed called");
getLoaderManager().restartLoader(LIST_LOADER,null,this);
super.onResume();
}
in GuivActivity.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.viewpagerindicator.TitlePageIndicator
android:id="@+id/titleindicator"
android:layout_height="wrap_content"
android:layout_width="fill_parent" />
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="@android:color/white"/>
in the fragment adatper
@Override
public Fragment getItem(int position) {
switch(position){
case 0:
return new ListFragment();
case 1:
return new SearchFragment();
default:
break;
}
return null;
}
Solution 1
ListFragment listFragment = (ListFragment) pagerAdapter.instantiateItem(viewPager, position)
Solution 2 It's a hack
ListFragment listFragment = (ListFragment) getSupportFragmentManager().findFragmentByTag(
"android:switcher:" + R.id.viewpager + ":" + viewPager.getCurrentItem());
Note But I would suggest you to use FragmentPagerAdapter
. It would give you much more control than PageAdapter
Why don't you call your fragment class to get the view? then call add on your fragment manager. It's a lot cleaner that way and easier to implement the "back" button.
public void displayView(int position, Bundle arguments) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new ListFragment();
break;
case 1:
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
String backStateName = fragment.getClass().getName();
boolean fragmentPopped = fragmentManager.popBackStackImmediate (backStateName, 0);
if (!fragmentPopped&&fragmentManager.findFragmentByTag(backStateName) == null){ //fragment not in back stack, create it.
FragmentTransaction ft =fragmentManager.beginTransaction();
ft.replace(R.id.frame_container, fragment,backStateName);
ft.addToBackStack(backStateName);
ft.commit();
}
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
if (position==0){
}
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
Coincidentially I was tackling the same problem today. They key is to instantiate the adapter like this:
mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
mCurrentFragment = (Fragment) object;
}
};
Now everytime the view pager switches to another fragment (even on first load and screen orientations) that fragment will be loaded into the mCurrentFragment
field variable (don't forget to declare it).
Pros: You don't have to work with internal fragment ids. I just tested it. And it's quite elegant.
Cons: None that I know of.
Note: Also don't forget to implement onSaveInstanceState(Bundle)
and onViewStateRestored(Bundle)
in your paged fragments if you need that. Based on true story.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.