I have two tabs with fragments created in my activity, the data of the second tab depends on the first tab data.
Both the tabs are containing list items, when I delete an item from first tab's list, it gets deleted but the second tab still shows the data. I need to go back from activity and load again to see the updated data in second tab.
Is there any way that I can refresh the second tab content whenever I delete/update list item of first tab?
Note: I have tried -
detach()
attach()
and
runQueryOnBackgroundThread()
notifyDataSetChanged()
In onResume nothing seems to be working. Any help would help a lot
You should learn about Interface communication. Read this http://developer.android.com/training/basics/fragments/communicating.html will help you.
you should override setUserVisibleHint method in your fragment and put your refreshing code in it
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser && isResumed()) {
}
}
I got this code in help.Hope it will help more people.Or refer my question here
http://stackoverflow.com/questions/40505019/how-to-refresh-tabs-content-dynamically-while-switching-between-one-tab-to-other/40505242#40505242
Related
I have 4 fragments in my viewpager I want to send a call for data every time when my fragment is visible to user. I am using uservisibilityhint() function but it is called only first time in view page and then again it is never called whenever that fragment is visible . is there any way to call it manually every time when the fragment is visible so that I can now that my fragment is visible or not to the user . how can i do this thing
Use
#Override
public void setUserVisibleHint(boolean visible) {
super.setUserVisibleHint(visible);
if (visible && isResumed()) {
// Your code
}
}
Use a Listener on your ViewPager in the Activity like below:
viewPager.setOnPageChangeListener(new OnPageChangeListener...
and here in the listeners callback detect the current View using this method:
ViewPager.getCurrentItem()
and then wire an interface between your activity and four fragments so you can notify which View should try loading fresh data.
I have a view pager which contains 2 fragment.
Now when user loads the activity, both of view gets loaded, they both contain analytics tag, and apps sends view tag from both of the fragments.
I want to restrict this. I want it to not execute any code from fragment2 unless user taps on it from view pager tab.
In the case of ViewPager, it is not possible I think...the minimum offScreenPageLimit is default set to 1. So it will load one page each side by default. So better you make it a custom view and load fragment according to the user taps.
Or check this workaround maybe this can be helpful in your case. I have never tried it but you can give it a shot
you can do the stuff after fragment gets visible
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
}
else {
}
}
The best implementation of a viewpager is to recycle the viewpager items. And you can achieve it by using offScreenPageLimit.
However, answering your question, i have faced similar situation myself and there is no perfect solution yet to achieve such a scenario. But there are certain hacks that you can do.
One solution is to use
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
}
else {
}
}
This will execute only when fragment is visible to user.
But this function too has some pitfalls. In some edge cases, this doesn't execute as well which will lead to an empty fragment.
The hack that I do is to use "OnTabSelectedListener" if I am integrating viewpager with tablayout and if there is only Viewpager you can override "OnPageSelectedListener".
If you are using OnTabSelectedListener, you will get callbacks in "OnTabSelected()" method when a tab is selected. So when you get the callback, use a public function in the respective fragment to load the data(Api calls, setting adapter etc).
Hope this helps
There is a ViewPager with Fragments generated dynamically.
Questions:
What is the way to catch the moment when user slides away from the fragment (so I can bring it into "clean", "init" state)?
or
How to catch moment when a Fragment is scrolled in?
Problems:
Have checked Fragment Lifecycle, but none of them is getting triggered when scrolled out/in (using ViewPager)
Lifecycle phases are triggered only if I scroll 2+ Fragments (those 3rd one is getting Paused/Resumed).
To get a callback when a fragment gets visible to the user you can override the setUserVisibleHint method, like this:
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser){
//Put your 'init' logic here
}
}
the variable isVisibleToUser will give the status of the visibility, so you can use the same method to handle when the fragment goes out.
addOnPageChangeListener
void addOnPageChangeListener (ViewPager.OnPageChangeListener listener)
Add a listener that will be invoked whenever the page changes or is incrementally scrolled. See ViewPager.OnPageChangeListener.
Components that add a listener should take care to remove it when finished. Other components that take ownership of a view may call clearOnPageChangeListeners() to remove all attached listeners.
You can implement this listener to track the movement of the fragments in the ViewPager.
There is also a method setOffscreenPageLimit() which Set the number of pages that should be retained to either side of the current page and it's default value is 1 and minimum value can be set to 0.
I am looking for and example source code for stop pre-loading pages in viewpager. Normally android viewpager loads the next and previous page(s) automatically. My target is to use viewpager and I want to show animation on views(which are present in the pages) when it visible to the user. Basically it is to continue with the previous of post.
If you can give me any working example(complete code) it will be so kind. I found so many but did not find any working implementation.
Thanks for your help.
Regards
Biswajit
Like you already know there is no way of stopping viewpagers from loading . The only way out is to use this method setUserVisibleHint add this to your fragment, and do all the animation you want to in this method
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// animate here
Log.e(TAG, "animate here");
}else{
Log.e(TAG, "fragment is no longer visible");
// fragment is no longer visible
}
}
This will be called only when that particular tab is visible to user.
i got viewpager with 4 tabs .. in each tab there is a fragment.
my first tab is a fragment with a form (for example Users)
after i click save, the data is inserted in the database.
my second tab is another fragment with form but it uses data from the first tab (i am getting it from the database) to populate a spinner.
now after i successfully inserted data from my first tab, in my second tab the spinner is empty. since my db query is implemented in onCreateView() in the second fragment, its called only once when the application is started, so changing between tab 1 i tab2 doesn't starts onCreateView() or even onResume().
The interesting thing for me is that if i go to tab4 and then return to tab2, my data is in my spinner properly, so somehow swiping two tabs away from my current tab refreshing my fragment.
my question is how can i achieve proper refresh to my fragment when onCreateView() is called only once ?
Edit
i tried to put that method psykhi suggested like that:
this.mViewPager.setOffscreenPageLimit(0);
this.mViewPager.setAdapter(this.mPagerAdapter);
this.mViewPager.setOnPageChangeListener(this);
but it's not working for me. Am i missing something ?
The best way that I have discovered to simulate a "setOffscreenPageLimit(0)" behavior is by using an OnPageChangeListener in conjunction with overriding the getItemPosition method in your adapter. Something like this:
In your custom pager adapter:
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
Then in your Activity containing the ViewPager:
final MyPagerAdapter adapter = new MyPagerAdapter();
pager.setAdapter(adapter);
pager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
... anything you may need to do to handle pager state ...
adapter.notifyDataSetChanged(); //this line will force all pages to be loaded fresh when changing between fragments
}
}
This should have the same effect as setting the OffscreenPageLimit to 0. However, this functionality is sort of against what the ViewPager is designed to provide. If you are trying to implement a ViewPager in this way, it may be worth reevaluating your layout to be sure that a ViewPager is really what you want to use.
UPDATE: There is a better way, Please have a look here: Update ViewPager dynamically?
Removing content of this answer because it was a really bad way to access Fragments inside ViewPager, please see the above link for better approach.
It's because you can specify the number of fragment your viewpager will "keep in RAM" (setOffScreenPageLimit () :I think the default is 1). So your second fragment is not reloaded. And when you go to a tab 3 or 4, then your 2 firsts fragments are deleted, then recreated when you come back.
To refresh your fragment, there is many way to do it: you could implement a listener interface of your own in it to tell it when to refresh, or simply call a method that you would implement to update your contents.
first override in the fragment method
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser){
actionView();//call the method to be refreshed
}
else{
//no
}
}
In my experience, ViewPagers keep:
Your current tab
& 1 tab either side in memory
So when you switch between 1 and 2, nothing is happening under the hood - it's like they are simply being hidden / shown.
But when you navigate to tab 4, tabs 1 & 2 are destroyed (onDestroy() called), so when you navigate back to either of them, they are being re-created fresh (onCreate() called).
As psykhi suggests, you could setOffScreenPageLimit() to 0, so that each fragment is created every time you navigate to it.
If you were interested in keeping the other pages in memory for performance purposes, as they were designed with this is mind, you could use a messaging/event publishing system to send a message from tab 1 to tab 2 telling it to update when you submit the form on tab 1.
Ok may be a late reply,might help others in future, so recently I faced same issue while fetching data from db into tabs it used to display only once I click on 3rd tab.. I tried above mentioned solution but nothing really worked.. fianlly i came across Otto
This library allows you to communicate within your app..
Just use this library to yourAdapter.notifyDataSetChanged() wherever you fetching your data from db..
This video helped me alot https://www.youtube.com/watch?v=lVqBmGK3VuA