Android Viewpager.setCurrentitem () and FragmentPagerAdapter fragments instantiateItem () initialize mismatch
I have a problem with FragmentPagerAdapter
, I set fragments in the viewpager via FragmentPagerAdapter
, I have to dynamically show the viewpager, I have the listview data that I need to show in the viewpager, when I click on the list I have to load the exact position in the viewpager so I just set the total size element to display in the FragmentPagerAdapter, but the problem is when I select the position of the viewpager through mPager.setCurrentItem(listposition)
, it shows the correct position of the viewpager, but loading the data in the wrong place, it loads into the next fragment at the position of the viewpager.after some tracking in the FragmentPagerAdapter, I show that the instantiateItem method initializes one fragment in advance, for example I set the currentitem (from the list) of the viewpager 2 then the instantiateItem method initializes 0 to 3 fragments, I think the reason the data is loading in the 3rd fragment , I tried a lot with FragmentStatePagerAdapter but had no success , please help me, thanks in advance.
Mainactivity (Fragmnetactivity) class:
public class NewsDetail extends FragmentActivity implements OnClickListener {
public static ViewPager mPager;
private static int NUM_PAGES;
private PagerAdapter mPagerAdapter;
public static ArrayList<Integer> exist_detail = new ArrayList<Integer>();
public static ArrayList<PageFragment> detailfragment = new ArrayList<PageFragment>();
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
NUM_PAGES = topList.size();
PageFragment fragment = new PageFragment();
Bundle args = new Bundle();
args.putInt("page", i);
fragment.setArguments(args);
detailfragment.add(fragment);
mPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
if (PageFragment.getInstance() != null) {
Log.d("LOG","PageFragment || "+ PageFragment.getInstance());
PageFragment.getInstance().startLoadingNews(
MusicList.topMusicList.get(arg0)._id);
}
return;
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {}
@Override
public void onPageScrollStateChanged(int arg0) {}
});
mPagerAdapter.notifyDataSetChanged();
mPager.setCurrentItem(listposition);// setcurrent item from here , it is selected from list. "listposition" indicate list position click
private class ScreenSlidePagerAdapter extends FragmentPagerAdapter {
private FragmentManager mFragmentManager;
private FragmentTransaction mCurTransaction = null;
private Fragment mCurrentPrimaryItem = null;
private static final boolean DEBUG = false;
public ScreenSlidePagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
this.mFragmentManager = fragmentManager;
}
@Override
public Fragment getItem(int position) {
return detailfragment.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return super.getItemId(position);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
Log.v("LOG", "On InstantiateItem " + position);// it indicate that this method initialize one fragment in advance.
return super.instantiateItem(container, position);
}
public String makeFragmentName(int viewId, long index) {
return "android:switcher:" + viewId + ":" + index;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
if (DEBUG)
Log.e("LOG", "Detaching item #" + position + ": f=" + object
+ " v=" + ((Fragment) object).getView());
mCurTransaction.detach((Fragment) object);
}
@Override
public void restoreState(Parcelable state, ClassLoader loader) {
}
@Override
public int getCount() {
return NUM_PAGES;
}
}
}
PageFragment
public class PageFragment extends Fragment implements OnClickListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPageNumber = getArguments().getInt(ARG_PAGE);
mDetailPageFragment = this;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout containing a title and body text.
rootView = (ViewGroup) inflater.inflate(R.layout.newsdetail, container,
false);
//init();
return rootView;
}
public void startLoadingNews(String _id) {
if (NetworkUtil.cheackNetwork(mActivity)) {
executeTask(_id);
} else {
showRetryCancelDialog();
}
}
}
source to share
In the code you posted, I see two problems:
- Create instances only
FragmentPagerAdapter.getItem
. Don't instantiate or store them in any list or array, let itFragmentPagerAdapter
do it for you. InFragmentPagerAdapter.instantiateItem
it checks if it has already been createdFragment
, and if it returns it, if not, it will call yoursgetItem
to create the fragment. - Don't use schema
Singleton
for your fragment, create a new fragment using constructor or static helper.newInstance()
.
source to share