FragmentStatePagerAdapter handling getItem() position

让人想犯罪 __ 提交于 2019-12-10 17:55:47

问题


I tried this, but wrong lists get binded to the recyclerview. I tried SparseArray as well, even that doesn't work. getItem() gets called twice when i start Mainactivity. How do I handle the position returned? I tried returning viewpager currentItem, even that doesn't work.

MainActivity

public class PagerAdapter extends FragmentStatePagerAdapter {
    int mNumOfTabs;


    public PagerAdapter(android.support.v4.app.FragmentManager fragmentManager, int tabCount) 
    {
        super(fragmentManager);
        this.mNumOfTabs = tabCount;    
    } 

    @Override
    public Fragment getItem(int position) {

        return Categories_Fragment.newInstance(position);

    }

    @Override
    public int getCount() {
        return mNumOfTabs;
    }

}

Categories_Fragment

public class Categories_Fragment extends Fragment 
{
private RecyclerView lvMessages; 
private int fromPage;


public static Categories_Fragment newInstance(int num) {
    Categories_Fragment f = new Categories_Fragment();

    // Supply num input as an argument.
    Bundle args = new Bundle();
    args.putInt("from", num);
    f.setArguments(args);

    return f; 
}


@Override
public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    fromPage = getArguments().getInt("from"); 


}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {      
    // TODO Auto-generated method stub  
    View rootView = inflater.inflate(R.layout.categories_filter, container, false); 
    lvMessages    = (RecyclerView)rootView.findViewById(R.id.lv_categories_filter);

    LinearLayoutManager x =  new LinearLayoutManager(getActivity()); 
    x.setOrientation(LinearLayoutManager.VERTICAL); 

    lvMessages.setLayoutManager(x);   


    return rootView; 
}


@Override
public void onActivityCreated(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onActivityCreated(savedInstanceState);

    // bind different data to the RecyclerView based on fromPage value. 

    }

}

回答1:


Here's what may be the kicker...

@Override
public void setUserVisibleHint(boolean isVisible) {
    super.setUserVisibleHint(isVisible);
    if (isVisible) {
        // bind to stuff using value of fromPage from here
    }
}

public void setUserVisibleHint (boolean isVisibleToUser): Set a hint to the system about whether this fragment's UI is currently visible to the user. This hint defaults to true and is persistent across fragment instance state save and restore.

What might be the problem (if I'm understanding your question correctly) is the pager is passing along its "last known" position, which doesn't necessarily mean is the position of the fragment that is currently being displayed on the device screen.

UPDATE: here's a complete example with a ViewPager handling the same fragment but with different data passed to it:

public class ViewPagerAdapter extends FragmentStatePagerAdapter {

    private JSONArray itemsArray;
    private int fragmentId;

    public ViewPagerAdapter(JSONArray itemsArray, int fragmentId, FragmentManager manager) {
        super(manager);
        this.itemsArray = itemsArray;
        this.fragmentId = fragmentId;
    }

    @Override
    public Fragment getItem(int position) {
        JSONObject itemObject = new Listing(itemsArray, position).getObject();
        Bundle bundle = new Bundle();
        bundle.putString("item_object", itemObject.toString());
        bundle.putInt("item_position", position);
        bundle.putInt("total_items", getCount());
        bundle.putInt("fragment_Id", fragmentId);
        Fragment fragment = new ListingFragment();
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public int getCount() {
        return itemsArray.length();
    }

}

Here's the Listings fragment (minus unimportant bits):

public class ListingFragment extends Fragment {

    private Listing listing;

    private String itemObject;
    private int itemPosition;
    private int totalItems;
    private int fragmentId;

    public ListingFragment() { }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle bundle = getArguments();
        itemObject = bundle.getString("item_object");
        itemPosition = bundle.getInt("item_position");
        totalItems = bundle.getInt("total_items");
        fragmentId = bundle.getInt("fragment_Id");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        View view = ...
        // nothing special to see here, just the usual stuff
        return view;
    }

    @Override
    public void setUserVisibleHint(boolean isVisible) {
        super.setUserVisibleHint(isVisible);
        if (isVisible) {
            // send fragmentID to wherever you want to use it
            // such as your recyclerview/adapter from here
         }
     }

}

I hope the example sheds some light, I know it works for me without fail.




回答2:


It is suspicious that you created a class called PagerAdapter, which is an Android abstract class. Rename it to a unique name like MyPagerAdapter.




回答3:


The reason why the getItem() is called twice is because of the default value assigned to offScreenPageLimit in ViewPager.

you can set the offScreenPageLimit to 1 or 0 using setOffscreenPageLimit (int limit) method of ViewPager class, and this will solve your problem of calling getItem() twice.

Hence, if getItem() is called once, then you will get the correct position value in the fragment and your problem wil lbe resolved.

checkout the link for method definition and description

http://developer.android.com/reference/android/support/v4/view/ViewPager.html#setOffscreenPageLimit(int)




回答4:


Using FragmentStatePagerAdapter ,HashMap<Integer,Demo_Fragment>

 public class ViewPagerAdapter extends FragmentStatePagerAdapter {
        List<String> mList;

        public ViewPagerAdapter(FragmentManager fm, List<String> list) {
            super(fm);
            mList = list;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            String  title = mList.get(position);
            return title;
        }

        public int getCount() {
            return mList.size();
        }

        public Fragment getItem(int position) {
            Demo_Fragment fragment = new Demo_Fragment();
            Bundle bundle = new Bundle();
            bundle.putString("text",mList.get(position));
            fragment.setArguments(bundle);
            fragment.setTags(position);
            mPageReferenceMap.put(position, fragment);

            return fragment;
        }

        public void destroyItem(ViewGroup container, int position, Object object) {
            super.destroyItem(container, position, object);
            mPageReferenceMap.remove(position);
        }

        public int getItemPosition(Object item) {
            Demo_Fragment fragment = (Demo_Fragment) item;
            int position = fragment.getTags();
            if (position >= 0) {
                return position;
            } else {
                return POSITION_NONE;
            }
        }
    }

For get Fragment

public Demo_Fragment getFragment(int key) {
        return mPageReferenceMap.get(key);
    }

For get current Fragment in addOnPageChangeListener ViewPager

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }

            @Override
            public void onPageSelected(int position) {
                final Demo_Fragment demo_Fragment = getFragment(mViewPager.getCurrentItem());
                final String str = mArrString.get(mViewPager.getCurrentItem());
                demo_Fragment.updateView(str);
                showDialog();
                mRunnable = new Runnable() {
                    @Override
                    public void run() {
                        randomGenerator = new Random();
                        randomInt = randomGenerator.nextInt(10000);
                        demo_Fragment.updateView(str +"\n" +randomInt+"-Updated Value");
                        hideDialog();
                    }
                };
                mHandler.postDelayed(mRunnable, 2000);


            }

            @Override
            public void onPageScrollStateChanged(int state) {
            }
        });

Working example - Click Here



来源:https://stackoverflow.com/questions/33706456/fragmentstatepageradapter-handling-getitem-position

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!