Load selected/active tab content in view pager - android

I'm having a view pager in an application which is dynamically populated based on content available on server i.e tabs in view pager is variable. To do this I have created a single fragment which is binds to each tabs inside view pager.
I have populated viewpager like this:
List lstFragments = lstFragments = new ArrayList();
lstFragments.add(DetailsFragment.newInstance(cat.getId(), subcategoryId, cat.getName(), subcategoryName, subcategoryIconUrl));
DetailsTabsAdapter pageAdapter = new DetailsTabsAdapter(getChildFragmentManager(), lstFragments);
viewPager.setAdapter(pageAdapter);
By default viewpager has property that its load content for one previous and one next fragment, but I don't want this.
What I want to achieve:
Load content of only selected/active tab.
At the same time once content is loaded for that tab I don't want to
load it again from server if user comes back.
How to achieve above functionality?
What I have did to achieve this:
I have loaded content from server in fragment's public View
onCreateView() lifecycle event. Content is loading fine but it
loads content for other tab as well.
Then I tried viewPager.setOffscreenPageLimit(0). But it also not working.
Please help me out to resolve this.
Thanks

For Issue 1
You need to implement public void setUserVisibleHint(boolean isVisibleToUser) like below:
boolean isDataLoaded = false;
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser && !isDataLoaded ) {
loadData();//Load data from server here
isDataLoaded = true;
}
}
Above code will load data only when your fragment will be visible to user and isDataLoaded flag ensure that content is loaded once per fragment lifecycle.
For issue 2
You need to store data you want to show to user as global within that fragment in your case DetailsFragment and check its value before loading it from server. May be you can do like below code.
boolean isDataLoaded = false;
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser && !isDataLoaded ) {
loadData();//Load data from server here
isDataLoaded = true;
}
else if(isDataLoaded && yourData != null)
{
//Load your data from cache or existing global instance here
}
}

There is a method called setUserVisibleHint() you can override it in your Frament. Which is called when the Fragment is visible. Now you can call the service to load data inside that method. And at the same time in the same method check for data if it is already loaded (saved in db) then call the service otherwise load the data from saved once.
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
// check if fragment is visible
if (isVisibleToUser) {
if(mdata == null){
callService();
} else{
loadFromSavedDB();
}
}
}

In you fragment call this
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser){
//Do what you want here`enter code here`
}
}

Related

I can't update the view of the visible Fragment

My problem, in a nutshell, is: I am calling a method of a fragment before onResume() and I don't know why.
I am not using setRetainInstance. I have an activity with a SearchView and a ViewPager. I have also a FragmentStatePagerAdapter which saves 2 fragments in a List<Fragment>.
My SearchView has the activity as a listener of OnQueryTextListener.
When I submit, inside the listener onQueryTextSubmit I call:
//make changes in shared preferences
Fragment fragment = mAdapter.getItem(viewPager.getCurrentItem());
((View) fragment).onLocationChange();
The implementation of onLocationChange in each fragment is:
#Override
public void onLocationChange() {
//avoid null pointer when is called too early in the life cycle
if (isResumed()) {
onResume();
}
}
The problem is sometimes isResumed is suddenly false so I can't update the view of the visible Fragment. I can see the changes only changing my current tab and detecting the change in the fragment:
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
isVisible = isVisibleToUser;
// Make sure that fragment is currently visible
if (isVisible && isResumed()) {
onResume();
}
}
Why might is not work sometimes? My onResume looks like:
#Override
public void onResume() {
super.onResume();
if (!getUserVisibleHint()) {
return;
}
//work here
}

In Tablayout I have added some tab and in that when I am switching between the tabs fragment refreshes its data? Why?

private Boolean isStarted = false;
private Boolean isVisible = false;
#Override
public void onStart() {
super.onStart();
isStarted = true;
if (isVisible && isStarted){
loadData();
}
}
//
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
isVisible = isVisibleToUser;
if (isVisible && isStarted) {
loadData();
}
}
what i am trying to do is when I launch the app data comes from db and shown in tab1 when i click on tab2 it again hits db and bring data and display. The problem arise when i came back to tab1 then it again hits db and bring data and again sets data in tab1 but its data is already loaded.
I already set the viewPager.setOffscreenPageLimit(1);.
Need help?
Thanks
Its default behaviours of ViewPager, its hold only two fragments at a time, if you want to load all the fragment in all time then you should go with setOffscreenPageLimit(), set the maximum of the limit of view pager item that you want to show. After then your fragment is not being refreshed.
You override this setUserVisibleHint() method remove this method and call loadData() data in onViewCreated() method,
Because setUserVisibleHint() call every time when your fragment is on screen.
viewPager.setOffscreenPageLimit(MAX_FRAGMENT);
As #Mohit Suthar says Its default behaviours of ViewPager, its hold only two fragments at a time,so you can change as follow
viewPager.setOffscreenPageLimit(1);
to
viewPager.setOffscreenPageLimit(FragmentCount); //apply limit of how many you take fragment to prevent re create View
Finally Solved the Problem.
Just need to set the isStarted = false; and isVisible = false; and that worked. Thanks Guys for helping me.
set `isStarted = false;` and `isVisible = false;` inside `loadData();`

Execute Code Each Time a Fragment in FramentStatePagerAdapter is viewed

I am using a FragmentStatePagerAdapter to create a SlidingTabLayout with 3 tabs. I want to do something each time a Fragment is viewed on my screen. I've tried putting what I want to happen inside the onStart() of the respective fragment like so:
public void onStart() {
//Do This
}
but it only works when the Fragment is moved 2 fragments away (i.e. 1st to 3rd, 3rd to 1st). Is there a way to do something each time a fragment is viewed on screen?
you can override setUserVisibleHint()
public class MyFragment extends Fragment {
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// here fragment is visible to user
}
else {
}
}
}

What is the difference between Fragment.isVisible() and isVisibleToUser

When I use FragmentPagerAdapter , I have four Fragment ,A,B,C,D.
When it is A ,
in B onresume,
#Override
public void onResume() {
super.onResume();
if (LogUtil.isDebugable()) {
LogUtil.i(TAG, "isVisible()"+isVisible());
}
}
it returns ture , but in setUserVisibleHint(),
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
if (isVisibleToUser) {
Log.d(TAG, "VisibleToUser");
}else {
Log.d(TAG, "unVisibleToUser");
}
super.setUserVisibleHint(isVisibleToUser);
}
isVisibleToUser returns false...
What is the difference between them
I believe that you are using View Pager, and of course it happens
because whenever you are on a page in view pager, it loads the page next to it as well.
And isVisible() will return true, if fragment has been added, or has its view attached to the window and isVisibleToUser would be true if this fragment's UI is currently visible to the user

Android+Robotium: is view of ViewPager visible to user

I'm using a ViewPager to display 2 Fragments as tabs. Once the according activity is loaded, both fragments are loaded immediatly, while only the first one is visible to the user.
Therefore view.isShown() is not sufficent for testing, as this method returns true for the second fragment which is not visible to the user.
ViewAsserts.assertOnScreen(decorView, view) seems to behave the same way and is therefore useless for solving this problem.
I'm aware that some similar questions have been asked, but none of their answers is satisfying my needs. So how to test this behavior (using Robotium)?
Solution:
I solved it according to Leon's suggestion by using a flag within the fragment like this:
private static boolean isVisibleToUser = false;
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
MyFragment.isVisibleToUser = isVisibleToUser;
}
public static boolean isVisibleToUser() {
return isVisibleToUser;
}
implementing it as a static method I can use it in my test this way:
assertTrue(MyFragment.isVisibleToUser());
the only drawback to this solution is that I have to implement these 2 methods in every single Fragment I want to test this way... any improvements?
You could override setUserVisibleHint inside your fragment like this:
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
//Fragment is selected in ViewPager
//Put your "on appear" validation/loading here
}
}
This method will fire every time you show or hide the fragment in the ViewPager.
As opposed to view.isShown() this method does take a "loaded but not visible" state into account.
use OnPageChangedListener to detect changes and maintain a reference to the currently visible fragment/page.
http://developer.android.com/reference/android/support/v4/view/ViewPager.OnPageChangeListener.html
Alternatively GetCurrentItem() may work for you as detailed here: How do you get the current page number of a ViewPager for Android?

Categories

Resources