I use FragmentStatePagerAdapter to manage my ViewPager. I have overwritten "getItemPosition" function. Here is my code:
mViewPager.setAdapter(new FragmentStatePagerAdapter(fm) {
#Override
public Fragment getItem(int position) {
Crime c = mCrimes.get(position);
return CrimeFragment.newInstance(c.getmId());
}
#Override
public int getCount() {
return mCrimes.size();
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
});
But the problem is that when I delete the first fragment, the last fragment will be deleted, but others work well. I don't know why.
Related
I have some sliders inside recyclerview among some other items. this is my pager adapter:
class PagerFragmentAdapter extends FragmentStatePagerAdapter {
public PagerFragmentAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
and i call setup on binding viewholder:
setup(RecyclerView.ViewHolder holder) {
pos = holder.getAdapterPosition();
if (pagerHolder == null) {
pagerHolder = (PagerHolder) holder;
viewPager = pagerHolder.getViewPager();
adapter = new PagerFragmentAdapter(fragmentManager);
viewPager.setAdapter(adapter);
pagerHolder.bindAdapter();
} else if(adapter!=null)
adapter.notifyDataSetChanged();
}
the first slider in recyclerview is OK but others are not OK!!
non of the fragments are loaded! and if i scroll it just shows first page of pager not all of them.
I have also tried creating fragments inside getItem() method but nothing changed..
I want to update container fragment base on data inside the page fragment in ViewPager. I used this solution Retrieve a Fragment from a ViewPager and it works fine when I swipe the view.
But I cannot figure out how to get hint (callback) if first page is loaded. At the beginning? Of course onPageSelected is called but when I try to get fragment I got null.
Data data = null;
mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
#Override
public void onPageSelected(int position) {
PageFragment page = MyPagerAdapter.getPageFragment(position);
if(page != null)
data = page.getData();
else
Log.w(TAG,"page is null"); //i get it at first time. :(
}
});
Below MyPageAdapter which I use (accordint to Retrieve a Fragment from a ViewPager)
public class MyPagerAdapter extends FragmentStatePagerAdapter {
SparseArray<PageFragment> registeredFragments = new SparseArray<PageFragment>();
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return ...;
}
#Override
public Fragment getItem(int position) {
return PageFragment.newInstance(...);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public PageFragment getPageFragment(int position) {
return registeredFragments.get(position);
}
}
I using view pager for swipe view for android app. I build view pager Dynamically. Like add and remove item. Now i want to know how to get exactly position of view pager items.For example, I have 3 items, i want to get 3rd number position when i am in 2nd or 1st item. i used viewPager.getCurrentItem() but it return where i am.
Please suggest me how to give personal ids of every viewpager items and used it in when item is background or on screen.Thanks please help me about this, i left 2 weeks already for this. Thanks in advance
public TabsPageAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
return new MyWebBrowser();
}
#Override
public int getItemPosition(Object object) {
return PagerAdapter.POSITION_NONE;
}
#Override
public int getCount() {
return COUNT_TAB;
}
}
Now this code Under my fragment class, from WebView chrom class i want to set up title as website title.
#Override
public void onReceivedTitle(WebView view, String title) {
TAB_TITLE=title;
Toast.makeText(HomeActivity.this,title,Toast.LENGTH_LONG).show();
super.onReceivedTitle(view, title);
}
take a look at this Adapter:
class MyAdapter extends FragmentStatePagerAdapter
{
private final SparseArray<WeakReference<YourFragment>> mPageReferences;
public MyAdapter(FragmentManager fm) {
super(fm);
mPageReferences = new SparseArray<WeakReference<YourFragment>>();
}
#Override
public Fragment getItem(int i) {
WeakReference<YourFragment> fragment =
new WeakReference<YourFragment>(YourFragment.newInstance());
mPageReferences.put(i, fragment);
return fragment.get();
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
mPageReferences.remove(position);
}
#Override
public int getCount() {
return number of fragment;
}
public YourFragment getFragment(int key) {
return mPageReferences.get(key).get();
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
WeakReference<YourFragment> fragment = new WeakReference<YourFragment>((YourFragment) super.instantiateItem(container,
position));
mPageReferences.put(position, fragment);
return fragment.get();
}
}
you can easily get the reference of any pages from mPageReferences BUT be careful because it may be null because it is possible that it has not created when you call it. you can use (getFragment(int key) to get the item at the position of key)
you can know the current position from the PagerAdapter.
by calling pageAdapter.getItemPosition(itemNumber)
link to the documentation
I am using FragmentStatePagerAdapter in my app.
My problem is that when I am doing notifyDataSetChanged() it's calling only the getCount() and not the getItem(). the getCount is not returning 0.
this is my FragmentStatePagerAdapter:
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
return titles.get(position);
}
#Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
#Override
public int getCount() {
return fragmentList.size();
}
}
How could it be that after pagerAdapter.notifyDataSetChanged(); only the getCount() is called and the getItem(int position) is not being called after it?
Thanks!
From Issue 19001, I found that int getItemPosition(Object object) needs to be implemented in the FragmentStatePageAdapter subclass. By default this method is assumed to return POSITION_UNCHANGED which will not trigger getItem to be called. However, I, also, ran into issues (possible bugs in the android support library) when I implemented anything other than return POSITION_NONE.
Snippet from my adapter:
#Override
public Fragment getItem(int position) {
return DiceRollerFragment.instantiate(position);
}
I tried to do what the other answers suggested, but when I look at the logs, after getItemPosition is returned with POSITION_NONE, position 0 does not get called for getItem, any idea? I also tried to override destoryItem when getItemPosition is returned, it DOES get called but nothing happens.
public class ProvidersActivityPagerAdapter extends FragmentPagerAdapter {
private ArrayList<String> fragments;
public ProvidersActivityPagerAdapter(FragmentManager fm) {
super(fm);
fragments=new ArrayList<String>();
if(provider.isInitialized()){
fragments.add(BaseDetailsFragment.class.getName());
}else{
fragments.add(BaseAuthFragment.class.getName());
}
this.fm=fm;
}
#Override
public int getCount(){
return fragments.size();
}
#Override
public int getItemPosition(Object object) {
AppUtils.logI("Get Item Position: "+POSITION_NONE+" "+object.getClass().getName());
return POSITION_NONE;
}
#Override
public Fragment getItem(int position) {
AppUtils.logI("Get Fragment for: "+position);
String f=fragments.get(position);
if(f.equals(BaseDetailsFragment.class.getName())){
return provider.getDetailFragment();
}
if(f.equals(BaseAuthFragment.class.getName())){
return provider.getAuthFragment();
}
if(f.equals(BaseSelectorFragment.class.getName())){
return provider.getCurrentSelector();
}
return new Fragment();
}
private void addItem(int loc,String fa,String tag){
this.fragments.add(loc,fa);
AppUtils.logI(fragments.toString());
notifyDataSetChanged(); //only creates the new fragment but not updating the old ones.
mViewPager.setCurrentItem(loc);
}
It appears that the support library version of the FragmentPagerAdapter does NOTHING in destroy item. So the solution is to save the fragment manager when constructing the page adapter and override the destoryItem() function. Note that this may not be compatible to future editions of the support library.
#Override
public void destroyItem(ViewGroup container,int position,Object object){
super.destroyItem(container, position, object);
FragmentTransaction bt = fm.beginTransaction();
bt.remove((Fragment)object);
bt.commit();
}