I am using a view pager with only one fragment.
I am doing this as the basic layout of the page would remain the same, only some of the details like text view and images would change and so I am re-using the same fragment for each
page in the view pager.
The question is that where and how do i pass the information to the fragment that I am currently on so and so page (ex: page#3). once the fragment has this information, it would be able to adjust its view/layout and display the following information.
could someone please help?
Thanks.
When you add fragment dynamically into your viewpager use this way:
class ParentPagerAdapter extends FragmentPagerAdapter implements ViewPager.OnPageChangeListener {
private ArrayList<Fragment> fragments;
public ParentPagerAdapter(FragmentManager fm,
ArrayList<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
#Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
#Override
public void onPageSelected(int position) {
// TODO Auto-generated method stub
((MYFragment)this.fragments.get(position)).updateLayout();
}
}
Attach instance of adapter as ViewPager's OnPageChangeListener().
Like this mPager.setOnPageChangeListener(myParentPagerAdapter);
either keep an instance of the fragment once you create it or use
MyFragment myFrag = (MyFragment)getFragmentManager().findFragmentById(r.id.myfragment);
to get the fragment by its id
mPager.setOnPageChangeListener(new OnPageChangeListener(){
#Override
public void onPageScrollStateChanged(int state) {
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int currentPage) {
MyFragment myFrag = (MyFragment)getFragmentManager().findFragmentById(r.id.myfragment);
myFrag.updateLayout(currentPage);
}
});
Related
I am using a viewPager for its swipe abilities to swipe between two Fragments. However I want to refresh the Fragment contents on swipe. The FragmentStatePagerAdapter does a very good job of caching so its hard to get the Fragment to reload. I've tried putting everything in the onResume method but that has no effect.
Here is my code
slideadapter=new ScreenSlidePagerAdapter(this.getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mViewPager.setOffscreenPageLimit(1);
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int i, float v, int i2) {
//Not used
Log.v("TAG","onPageScrolled");
}
#Override
public void onPageSelected(int position) {
//Force the fragment to reload its data
Fragment f = slideadapter.getItem(position);
f.onResume();
}
#Override
public void onPageScrollStateChanged(int i) {
//Not used
Log.v("TAG","onPageScrollStateChanged");
}
});
mSlidingTabLayout = (SlidingTabLayout)findViewById(R.id.sliding_tabs);
mViewPager.setAdapter(slideadapter);
mViewPager.setCurrentItem(0);
mSlidingTabLayout.setViewPager(mViewPager);
you can override setUserVisibleHint method in your Fragments
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
doSomething();
}
}
Use the ViewPager.onPageChangeListener:
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
public void onPageScrollStateChanged(int state) {}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
public void onPageSelected(int position) {
// get fragment by position and do whatever you want to do on fragment selection.
}
});
you can try mViewPager.setOffscreenPageLimit(1); if you want to call the onresume method everytime the fragments becomes visible
Create a BaseFragment class with a method ex. loadData (),where
Viewpager child fragments extends from this BaseFragment and override the loadData () method and do the operation.
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
public void onPageScrollStateChanged(int state) {}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
public void onPageSelected(int position) {
if (slideadapter.getFragment(position) instanceof BaseFragment) {
((BaseFragment) slideadapter.getFragment (position)).loadData ();
}
}
});
In the SlideAdapter create method called
public Fragment getFragment(int key) {
return mPageReferences.get(key);
}
private final SparseArray<Fragment> mPageReferences = new SparseArray<Fragment>();
//add created fragment refernce to this array
#Override
public Fragment getItem(int position) {
mPageReferences.put(position, fragment);
}
//remove the reference when destroy
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
mPageReferences.remove(position);
}
Hope this will help!
I am using view pager. In this view pager i have 3 page. When i am running the app. view pager create left center and right fragment instance and all life cycle method are called. my problem is that i need to show some data when i select middle page. but i am not able to get any callback method to do. please help me. thanks in advance.
Adapter
public class ViewPagerFragmentPageAdapter extends FragmentPagerAdapter {
Context mContext;
public ViewPagerFragmentPageAdapter(Context context, FragmentManager fm) {
super(fm);
mContext = context;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return BusinessCategoryFragment.getInstance();
case 1:
return FavoriteFragment.getInstance(mContext.getResources().getString(R.string.favorite));
case 2:
return RecentFragment.getInstance(mContext.getResources().getString(R.string.recent));
default:
return BusinessCategoryFragment.getInstance();
}
}
#Override
public int getCount() {
return 3;
}
}
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewFragmentPageAdapter = new ViewPagerFragmentPageAdapter(
HomeActivity.this, getSupportFragmentManager());
mViewPager.setAdapter(mViewFragmentPageAdapter);
You can use the onPageChangelistener and handle data refreshing code in the overrided methods of the listener.
vPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// here u can add necessary code for refreshing data
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {}
#Override
public void onPageScrollStateChanged(int arg0) {}
});
Is there anyway to create a limited Fragment + ViewPager with Infinite Scrolling?
For example :
I am going to create 10 Fragment, when I scroll to the fifth Fragment, index number 0 Fragment destroyed and appear the eleventh Fragment
**1** 2 3 4 5 6 7 8 9 10
after scroll to the fifth
2 3 4 **5** 6 7 8 9 10 11
Variable
private static final int NUM_PAGES = 10;
Here is my Fragment adapter
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return PageFragment.create(position);
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
Here is the contain of the Fragment to show begin with number 1
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.fragment_view, container, false);
((TextView) rootView.findViewById(R.id.tvUsername)).setText(
""+ (mPageNumber + 1));
return rootView;
}
Here is when the selected event occur
mPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int pageSelected) {
// TODO Auto-generated method stub
Log.d(TAG, "selected = " + pageSelected);
if (pageSelected > (NUM_PAGES - 6)) {
//Event do it here?
}
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
});
Question :
How to create the event?
I think that can be done with changing the position value in the getItem().
But I don't know how to do it
The only way i could come up with is to make only three pages and when the user scrolls to the last page, you replace every fragment. Something like this:
The array
ArrayList<Integer> positions = new ArrayList<Integer>();
public void initPositions() {
positions.add(0);
positions.add(1);
positions.add(2);
}
The adapter
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return PageFragment.create(positions.get(position));
}
#Override
public int getCount() {
return 3;
}
}
The listener
mPager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int pageSelected) {
//scrolled to first page
if(pageSelected == 0) {
//Make sure its not unlimited upwards
if(positions.get(pageSelected == 0))
return;
//remove last and insert new at bottom
positions.remove(2);
positions.insert(0, positions.get(0) - 1);
//scrolled to last page
} else if(pageSelected == 2) {
//remove first and add one last
positions.remove(0);
positions.add((positions.get(1) + 1) % NUM_PAGES);
}
//make sure the adapter understands
mAdapter.notifyDataSetChanged();
//move pager to the middle again
mPager.setCurrentItem(1);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
});
Not sure how this would work performancewise, or if it would work at all, but give it a shot :)
I am using view-pager.In that I have three tabs : 1. History , 2. Main , 3. Map .
I have stopwatch into main activity.When I press the start and then after stop at that time value of the stopwatch add into the sqlite DB. And into history activity I am fetching the value of stopwatch from DB and store into the listview. It's working perfect.
But now I want the update the History activity when I swipe from the Main > History so After press the stop button,I got the last value into listview of history activity.
My question is how can I update the view on swipe the viewpager?
public class SwipeyTabsSampleActivity extends FragmentActivity {
private static final String [] TITLES = {
"HISTORY",
"MAIN",
"MAP"
};
private SwipeyTabs mTabs;
private ViewPager mViewPager;
//Handler handler=new Handler();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_swipeytab);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mTabs = (SwipeyTabs) findViewById(R.id.swipeytabs);
SwipeyTabsPagerAdapter adapter = new SwipeyTabsPagerAdapter(this,
getSupportFragmentManager());
mViewPager.setAdapter(adapter);
mTabs.setAdapter(adapter);
mViewPager.setOnPageChangeListener(mTabs);
mViewPager.setCurrentItem(1);
mViewPager.setOffscreenPageLimit(3);
}
private class SwipeyTabsPagerAdapter extends FragmentPagerAdapter implements
SwipeyTabsAdapter, ViewPager.OnPageChangeListener {
private final Context mContext;
ViewPager viewpager;
public SwipeyTabsPagerAdapter(Context context, FragmentManager fm, ViewPager mViewPager) {
super(fm);
this.mContext = context;
viewpager = mViewPager;
//viewpager.setAdapter(this);
viewpager.setOnPageChangeListener(this);
}
#Override
public Fragment getItem(int position) {
Fragment f = new Fragment();
switch (position) {
case 0:
f = History.newInstance(position);
break;
case 1:
f = Main.newInstance(position);
break;
case 2:
f = Map.newInstance(position);
break;
}
return f;
}
#Override
public int getCount() {
return TITLES.length;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
ViewPager pager = (ViewPager) container;
View view = (View) object;
pager.removeView(view);
}
public TextView getTab(final int position, SwipeyTabs root) {
TextView view = (TextView) LayoutInflater.from(mContext).inflate(
R.layout.swipey_tab_indicator, root, false);
view.setText(TITLES[position]);
view.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mViewPager.setCurrentItem(position);
}
});
return view;
}
#Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// TODO Auto-generated method stub
}
#Override
public void onPageSelected(int positiion) {
// TODO Auto-generated method stub
}
}
}
Add ViewPager OnPageChangeListener:
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
// your code here
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
This will affect the changes from one page to another page in view pager.
OnPageChangeListener pagechangelistener =new OnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
Logger.logMessage("Called first");
pageAdapter.notifyDataSetChanged();
indicator.setCurrentItem(arg0);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
Logger.logMessage("Called second");
}
#Override
public void onPageScrollStateChanged(int arg0) {
Logger.logMessage("Called third");
}
};
myViewPager.setOnPageChangeListener(pagechangelistener);
Use this in your page adapter.
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
Take one string and add the Getters and setters into your FragmentActivity class.
Like...
String HistoryFragment;
public String getHistoryFragment() {
return HistoryFragment;
}
public void setHistoryFragment(String historyFragment) {
HistoryFragment = historyFragment;
}
Then after we can access another fragment from our current fragment by calling findFragmentByTag(<tag of target fragment>).
For the more information check the link Communication between Fragments in ViewPager.
Have you tried implementing OnPageChanged`? You can capture when the user start swiping.
do pager.setOnPageChanged(new ....) and Eclipse will show you the methods you can override.
Then you can override onPageScrollStateChanged(int state)
onPageScrollStateChanged(int state){
if (state==OnPageChangeListener.SCROLL_STATE_DRAGGING){
// update here
}
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
ViewPager as a circular queue / wrapping
I have three fragment classes in my code.
FirstActivity,SecondActivity,ThirdActivity i want to swipe these three activities.. these three are extend from Fragment class
public class ViewPagerFragmentActivity extends FragmentActivity {
private PagerAdapter mPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
super.setContentView(R.layout.viewpager_layout);
initialisePaging();
}
/**
* Initialize the fragments to be paged
*/
List<Fragment> fragments = new Vector<Fragment>();
ViewPager pager;
private void initialisePaging() {
fragments.add(Fragment.instantiate(this, FirstActivity.class.getName()));
fragments.add(Fragment.instantiate(this, SecondActivity.class.getName()));
fragments.add(Fragment.instantiate(this, ThirdActivity.class.getName()));
this.mPagerAdapter = new MyPagerAdapter(super.getSupportFragmentManager(), fragments);
pager = (ViewPager) super.findViewById(R.id.viewpager);
pager.setAdapter(this.mPagerAdapter);
}
}
and here is my FragmentPageAdapter class
public class MyPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> fragments;
public MyPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
#Override
public Fragment getItem(int position) {
System.out.println("position"+position);
return this.fragments.get(position);
}
#Override
public int getCount() {
return this.fragments.size();
}
}
my code is working in this way A<->B<->c
but my requirement is to run like this wayC<->A<->B<->C<-A->
that is in circular fragments are swipable...
Circular ViewPager is possible.
With the help of ViewPager as a circular queue / wrapping this link have coded like this. Hope it helps what you needed.
The CircluarPagerAdapter class:
>
public class CircularPagerAdapter extends PagerAdapter{
private int[] pageIDsArray;
private int count;
public CircularPagerAdapter(final ViewPager pager, int... pageIDs) {
super();
int actualNoOfIDs = pageIDs.length;
count = actualNoOfIDs + 2;
pageIDsArray = new int[count];
for (int i = 0; i < actualNoOfIDs; i++) {
pageIDsArray[i + 1] = pageIDs[i];
}
pageIDsArray[0] = pageIDs[actualNoOfIDs - 1];
pageIDsArray[count - 1] = pageIDs[0];
pager.setOnPageChangeListener(new OnPageChangeListener() {
public void onPageSelected(int position) {
int pageCount = getCount();
if (position == 0){
pager.setCurrentItem(pageCount-2,false);
} else if (position == pageCount-1){
pager.setCurrentItem(1,false);
}
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// TODO Auto-generated method stub
}
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
}
});
}
public int getCount() {
return count;
}
public Object instantiateItem(View container, int position) {
LayoutInflater inflater = (LayoutInflater) container.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
int pageId = pageIDsArray[position];
View view = inflater.inflate(pageId, null);
((ViewPager) container).addView(view, 0);
return view;
}
#Override
public void destroyItem(View container, int position, Object object) {
((ViewPager) container).removeView((View) object);
}
#Override
public void finishUpdate(View container) {
// TODO Auto-generated method stub
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((View) object);
}
#Override
public void restoreState(Parcelable state, ClassLoader loader) {
// TODO Auto-generated method stub
}
#Override
public Parcelable saveState() {
// TODO Auto-generated method stub
return null;
}
#Override
public void startUpdate(View container) {
// TODO Auto-generated method stub
}
}
and this is your main class:
>
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager myPager = (ViewPager) findViewById(R.id.conpageslider);
PagerAdapter adapter = new CircularPagerAdapter(myPager, new int[]{R.layout.first_activity, R.layout.second_activity, R.layout.third_activity});
myPager.setAdapter(adapter);
myPager.setCurrentItem(3);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
You can try something like this :
1) Make getCount() return a huge value ( a number of swipe way higher than what your user might use )
2) Make getItem return something like this.fragments.get(position % fragments.size())
3) Make your pager start somewhere in the middle of the range defined by getCount() ( To allow swiping from A to C at the beginning ), make sure to choose a value which will give you the first fragment % 3
I'm aware this solution seems a bit dirty but I cant find a better one at the moment