I have Nested Fragments [1 main Fragment called "MainFrag" and many child Fragments]
the App can show MainFrag or can show other fragments.
what I want to do is to setCurrentItem of MainFrag's ViewPager every time the user selects to show that MainFrag so I tried to put it at it's onCreateView but this only works for the first time the User Shows MainFrag as if user Selects another fragment and then re-selects MainFrag the seCurrentItem is not working
I also tried to put it inside MainFrag's onResume, It worked as required but it also causes a problem that if the user moved the App to background and then reOpen it viewPager will Scroll and i don't want this
So where Exactly Can I put setCurrentItem ?
mViewPager.setCurrentItem(mCurrentWeekFragmentItemNumber);
Edit: I am using Navigation Menu to Move between 3 main fragments where MainFrag is one of them.
After your mViewPager.setAdapter(adapter); method you can put
mViewPager.setCurrentItem(mCurrentWeekFragmentItemNumber);
After setting adapter to viewpager add setCurrentItem method
mViewPager.setAdapter(adapter);
mViewPager.setCurrentItem(mCurrentWeekFragmentItemNumber);
Try this:
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
viewPager.setCurrentItem(position);
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
Related
Consider there is an activity with a title. Viewpager fragment is inside the activity. Fragment will be loaded with data from network API.
Now I need to update the activity title after getting the data from API.
Problem:
Since Viewpager is used, it loads the (prev), current, (next) fragments too. So activity is not aware of which title it is for.
Each title is different for each fragment, so I need to update the title only when the user views that fragment.
You need to create object of your Activity, By using this Object you are able to use activity method.
For more detail; visit this link.How to use method from another Class?
Use this with addOnPageChangeListener method of pager, in it you will get your current postion of pager.
In you Activity add the listener on ViewPager:
viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener()
{
#Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
{
}
#Override public void onPageSelected(int position)
{
//You can use switch case too
if (position== 0)
{
//set title
}
else if (position== 1)
{
//set title
}...
}
#Override public void onPageScrollStateChanged(int state)
{
}
});
You can call the Activity method from Fragment by
Make method in Activity public
In fragment use getActivty() -> cast it to corresponding Activity then call this method
If you want to call Activity method only when fragment visible you can try https://stackoverflow.com/a/42019934/5381331
In Activity, you want to get the current visible fragment, you can try https://stackoverflow.com/a/47789367/5381331
Well, I think the title is quite self explanatory. I have a ViewPager in my HomeActivity, the ViewPager contains 5 fragments at the moment.
When one of the fragments is visible by calling ViewPager's onPageScrolled I want to modify some views inside the current displayed fragment according to some conditions in the HomeActiviy.
After some research, it seems like I cannot find a good way to communicate in the direction HomeActivity --> Fragments inside ViewPager.
I have easily solved the communication in the direction Fragments in ViewPager --> HomeActivity using an Interfacebut this trick seems to not be working on the other direction.
I can access each time the current displayed fragment using a method on my FragmentStatePagerAdapter
public Fragment getActiveFragment(int position){
return myFragmentsList.get(position);
}
However, by doing that, I would have to cast each Fragment into its class MyFragment1 MyFragment2 MyFragment3....
Any easy clean way to achieve that?. Here is the relevant portion of the code:
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (currentStatus == 1){
Fragment activeFrag = mPagerAdapter.getActiveFragment(mPager.getCurrentItem());
//here I would like to modify one of the 5 fragments
}
#Override
public void onPageSelected(int position) {}
#Override
public void onPageScrollStateChanged(int state) {}
});
Define an interface,
interface FragmentListenerInterface {
public void onFragmentSelected();
}
Implement this interface in all of your fragments. change the communication between fragment and viewpager. write a method to return fragmentlistenerinterface instead of fragment.
public FragmentListenerInterface getActiveFragment(int position){
return (FragmentListenerInterface) myFragmentsList.get(position);
}
After this just say, in your code
public void onPageSelected(int position) {
mViewPager.getActiveFragment(position).onFragmentSelected();
}
And implement onFragmentSelected() in every fragment.
I created a new project in Android Studio that uses fragments and tabs to select a fragment.
So Android Studio created a project for me that uses a ViewPager to select the different fragments.
Unfortunately, ViewPager will create off-screen fragments and even trigger onResume() in the off-screen fragment !
This is a problem, since code in onResume() in fragment 2 depends on what a user does in fragment 1.
I've tried setting mViewPager.setOffscreenPageLimit(0); but this doesn't seem to have any effect, the neighboring fragment is still called with onResume() before it's actually shown.
QUESTION
What callback is triggered in a Fragment when it's actually shown?
Otherwise, how can I set it up so that I can adjust the UI in fragment 2 depending on what the user did in Fragment 1 ?
you can use setOnPageChangeListener() like this
mViewPager.setOffscreenPageLimit(1);
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
#Override
public void onPageSelected(int position) {
// TO DO
}
#Override
public void onPageScrollStateChanged(int state) {}
});
Currently I'm building an app with different tabs in it. In one of the tabs I have a camera fragment that I start and show to the user. To implement smooth swiping I want to load the tab content itself, so that the user his swiping doesn't hang. When it's loaded the camera should be started.
Is there some sort of a callback/listener/trick that can be used to see if a fragment is fully loaded?
Tab layout is bound to view pager using tablayout.setupWithViewPager(viewPager), so you can use view pager page listener to detect tab loaded event.
Official Documentation
If you're using a ViewPager together with TabLayout, you can call setupWithViewPager(ViewPager) to link the two together.
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
//tab loaded
}
#Override
public void onPageScrollStateChanged(int state) {
}
});`
It appears that many people are using setOnPageChangedListener() on the ViewPager. We ended up implementing this after noticing a race condition due to Fragments not loading synchronously due to using the FragmentManager. Check out the answer here.
Which lifecycle callback is called when a fragment pager adapter's fragment comes to screen?
I have a ViewPager with 10 pages. When I start the last (10th) page onCreateView() method of my fragment is called. When I swipe to the 9th page onCreateView() is called also. But when I back to the 10th page onCreateView() isn't called. What's wrong?
Try Extending FragmentStatePagerAdapter
That is because a FragmentPagerAdapter keeps in memory every fragment. Hence, when you visit the first time the fragment, onCreate will be invoked but the second time Android will looking for in memory, so it not need invoke onCreate.
If you need run the code in OnCreate every time fragment is displayed, you should move it to getItem(int id)
See offical documentation: http://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html
Nothing is wrong. The ViewPager already has the page, and so it does not need to create it.
I had the same problem, my solution was to assign again the adapter of the ViewPager instance, just like:
pager.setAdapter(adapter);
This causes a restart of the "mItems" property from the viewPager and removes the cache.
But I don't know if it's a safe solution
You can call the adapter getItem from onPageSelect, which is called also on swipes, and place your code inside the getItem, or even in the onPageSeelect itself.
CommonWare's answer is the best and works like charm:
simple add OnPageChangeListener to your ViewPager item, something like this:
ViewPager viewPager = null;
PagerAdapter pagerAdapter = null;
//Some code come here...
pagerAdapter = new PagerAdapter(); //Or any class derived from it
viewPager = (ViewPager)findViewById(R.id.container);//Connect it to XML
viewPager.setAdapter (mPagerAdapter); //Connect the two
//Next two lines are simply for fun...
//viewager.setPageTransformer(true, new DepthPageTransformer());
//viewPager.setPageTransformer(true, new PaymentZoomOutPageTransformer());
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
//This is the right place to connect the pages with a data struct!!!
#Override
public void onPageSelected(int position) {
// Here you can connect the current displayed page with some data..
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
//Here use the inflater to add views/pages
//Don't forget to do:
pagerAdapter.notifyDataSetChanged();
//When you're done...