Swapping out Fragments fails with FragmentStatePagerAdapter - android

I have the following...
Layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Adapter code...
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter implements ActionBar.TabListener {
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
private Fragment f;
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
this.addTab(actionBar.newTab().setText("Score"), ScoreFragment.class, null);
f = new TeamFragment();
this.addTab(actionBar.newTab().setText("Team"), TeamFragment.class, null);
}
#Override
public Fragment getItem(int position) {
if(position == 0){
TabInfo info = mTabs.get(position);
return Fragment.instantiate(context, info.clss.getName(), info.args);
}
else{
return f;
}
}
#Override
public int getCount() {
return mTabs.size();
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
actionBar.addTab(tab);
notifyDataSetChanged();
}
#Override
public void onTabReselected(Tab arg0,
android.app.FragmentTransaction arg1) {
// TODO Auto-generated method stub
}
#Override
public void onTabSelected(Tab tab, android.app.FragmentTransaction arg1) {
Object tag = tab.getTag();
for (int i = 0; i < mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mPager.setCurrentItem(i);
}
}
}
#Override
public void onTabUnselected(Tab arg0,
android.app.FragmentTransaction arg1) {
// TODO Auto-generated method stub
}
/**
* #return the f
*/
public Fragment getF() {
return f;
}
/**
* #param f the f to set
*/
public void setF(Fragment f) {
startUpdate((ViewGroup)findViewById(R.id.pager));
destroyItem((ViewGroup)findViewById(R.id.pager), 1, this.f);
this.f = f;
instantiateItem((ViewGroup)findViewById(R.id.pager), 1);
finishUpdate((ViewGroup)findViewById(R.id.pager));
notifyDataSetChanged();
}
}
However, when I call setF with a new fragment, the old one disappears as expected but the new one never shows up. Can someone help me with what I am doing wrong?
I tried changing to...
public void setF(Fragment f) {
ViewGroup g = (ViewGroup)findViewById(R.id.pager);
startUpdate(g);
destroyItem(g, 1, this.f);
this.f = f;
WebViewFragment v = (WebViewFragment)instantiateItem(g, 1);
FragmentManager fm = v.getFragmentManager();
finishUpdate(g);
Fragment f3 = v;
f3.setUserVisibleHint(true);
setPrimaryItem(g,1,v);
notifyDataSetChanged();
}
but now I get...
10-24 17:10:12.290: E/AndroidRuntime(1113): java.lang.NullPointerException
10-24 17:10:12.290: E/AndroidRuntime(1113): at android.support.v4.app.Fragment.setUserVisibleHint(Fragment.java:819)
10-24 17:10:12.290: E/AndroidRuntime(1113): at android.support.v4.app.FragmentStatePagerAdapter.setPrimaryItem(FragmentStatePagerAdapter.java:152)
10-24 17:10:12.290: E/AndroidRuntime(1113): at android.support.v4.view.ViewPager.populate(ViewPager.java:1066)
Looks like maybe a race condition?
ActionBar with ViewPager - clicking partially visible tab crashes the app
Update
If I remove the setPrimaryItem(g,1,v); then it appears to run fine till I go to another tab and come back. Then it fails the same way. This leads me to believe I am doing it somewhat right and just missing something.

Here is the functional version, I had to change multiple things around. I would still like to add to the BackStack (If you can do that you will get the check) but this should help anyone in the same boat.
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter implements ActionBar.TabListener {
private ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
private List<Fragment> fragments = new ArrayList<Fragment>();
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
fragments.add(new ScoreFragment());
fragments.add(new TeamFragment());
this.addTab(actionBar.newTab().setText("Score"), ScoreFragment.class, null);
this.addTab(actionBar.newTab().setText("Team"), TeamFragment.class, null);
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
actionBar.addTab(tab);
notifyDataSetChanged();
}
#Override
public void onTabReselected(Tab arg0,
android.app.FragmentTransaction arg1) {}
#Override
public void onTabSelected(Tab tab, android.app.FragmentTransaction arg1) {
Object tag = tab.getTag();
for (int i = 0; i < mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mPager.setCurrentItem(i);
}
}
}
#Override
public void onTabUnselected(Tab arg0,
android.app.FragmentTransaction arg1) {}
/**
* #param f the f to set
*/
public void setF(Fragment f) {
int loc = actionBar.getSelectedTab().getPosition();
fragments.set(loc, f);
notifyDataSetChanged();
}
#Override
public int getItemPosition(Object object) {
if(object instanceof Fragment){
if(fragments.contains(object))
return POSITION_UNCHANGED;
}
return POSITION_NONE;
}
}

Trying to using transition fragment to replace, add or remove fragments might doesn’t word sometimes and it just shows a blank layout. This problem happen because some reasons. I had the problem and I figured it out. It just was the way that I implemented onCreate method in my fragmentActivity.
This is is how it was:
protected void onCreate(android.os.Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mybooks);
}
And the problem was gone when I changed android.os.Bundle to just Bundle. I hope this help anybody who has same this problem.

Related

How to be sure fragments have been added to FragmentPagerAdapter?

I'm using a FragmentPagerAdapter to create a layout with 2 fragments, where user can swipe between them:
mTabsAdapter = new TabsAdapter(this, mPager);
mTabsAdapter.addTab(bar.newTab().setText("Tab 1"), FirstFragment.class, null);
mTabsAdapter.addTab(bar.newTab().setText("Tab 2"), SecondFragment.class, null);
Right after that, i want to get the added fragment to call its methods:
FirstFragment firstFragment = (FirstFragment) mTabsAdapter.findFragmentByPosition(pos);
The problem is at this time the tabs aren't ready yet, and findFragmentByPosition returns null. If I do this inside a Handler().postDelayed(new Runnable(){..., it does the trick when testing, but I still get this error from some users.
Is there a way to know if fragments are ready?
Below is the TabsAdapter class:
public static class TabsAdapter extends FragmentPagerAdapter implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final SherlockFragmentActivity mActivity;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i=0; i<mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
}
public void selectTabByPosition(int position){
mViewPager.setCurrentItem(position);
}
public Fragment findFragmentByPosition(int position) {
FragmentPagerAdapter fragmentPagerAdapter = this;
return mActivity.getSupportFragmentManager().findFragmentByTag(
"android:switcher:" + mViewPager.getId() + ":"
+ fragmentPagerAdapter.getItemId(position));
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
//
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
//
}
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActivity = activity;
mActionBar = activity.getSupportActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
#Override
public int getCount() {
return mTabs.size();
}
#Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrollStateChanged(int state) {
}
}
MainActivity.java
// Fragments and ViewPager Initialization
List<Fragment> fragments = getFragments();
pageAdapter = new MyPageAdapter(getSupportFragmentManager(), fragments);
mViewPager.setAdapter(pageAdapter);
mViewPager.setOnPageChangeListener(MainActivity.this);
MyPageAdapter.java
public class MyPageAdapter extends FragmentPagerAdapter
{
private List<Fragment> fragments;
public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
#Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
#Override
public int getCount() {
return this.fragments.size();
}}

Android, How to mix ActionBar.Tab + View Pager + ListFragment

I've been trying to test how to mix all these things together and I'm having problems!!
I just want an app with three tabs using the ActionBar.Tab. For example, this tabs can be movies genres Action, Adventure and Animation, the user can swipe through the tabs, so it will use the ViewPager and each tab will show a list of movies of that genre. There's no need to have three different fragments classes because all tabs will be the same format a simple list.
And I'm having problems because when I select the second tab, the position for onPageSelected is 1,
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mCollectionPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
});
This causes the call to the method public Fragment getItem(int i) inside the CollectionPagerAdapter class, but then the value of i is 2 NOT 1, so then it calls the createView for the TabFragment class with a value of 2 NOT 1, so tabs are not refreshing successfully.
Any help will be really appreciated!!
Code to create the tabs,
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mCollectionPagerAdapter.getCount(); i++) {
mActionBar.addTab(mActionBar.newTab()
.setText(mGenres.get(i).getName())
.setTabListener(this));
//Let's request the movies for the first three genres
new GetMoviesByGenre().execute(mGenres.get(i).getId());
}
When a tab is selected,
#Override
public void onTabSelected(ActionBar.Tab tab, android.app.FragmentTransaction arg1) {
//Let's update the dataset for the selected genre
TabFragment fragment =
(TabFragment) getSupportFragmentManager().findFragmentByTag(
"android:switcher:"+R.id.pager+":"+tab.getPosition());
if(fragment != null) // could be null if not instantiated yet
{
if(fragment.getView() != null)
{
fragment.updateDisplay(tab.getPosition()); // do what updates are required
}
}
mViewPager.setCurrentItem(tab.getPosition());
}
CollectionPageAdapter class
public class CollectionPagerAdapter extends FragmentPagerAdapter {
final int NUM_ITEMS = 3; // number of tabs
List<Fragment> fragments = new ArrayList<Fragment>();
public Fragment getItem(int pos) {
return fragments.get(pos);
}
public void addFragment(Fragment f) {
fragments.add(f);
}
public CollectionPagerAdapter(FragmentManager fm) {
super(fm);
//Let's add the fragments
for (int i=0;i<NUM_ITEMS;i++)
{
Fragment fragment = new TabFragment();
Bundle args = new Bundle();
args.putInt(TabFragment.ARG_OBJECT, 0);
fragment.setArguments(args);
addFragment (fragment);
}
}
#Override
public int getCount() {
return NUM_ITEMS;
}
}
TabFragment class
public class TabFragment extends ListFragment {
public static final String ARG_OBJECT = "object";
private MoviesAdapter m_Adapter;
private ArrayList <Movie> mMovies = new ArrayList<Movie>();
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// you only need to instantiate these the first time your fragment is
// created; then, the method above will do the rest
if (m_Adapter == null) {
m_Adapter = new MoviesAdapter(getActivity(), mMovies);
}
setListAdapter(m_Adapter);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
int position = getArguments().getInt(ARG_OBJECT); // to check is the right fragment
View rootView = inflater.inflate(R.layout.tabs, container, false);
return rootView;
}
public void updateDisplay (int type)
{
GlobalVars gv = (GlobalVars)getActivity().getApplicationContext();
switch (type)
{
case 0:
mMovies = gv.getActionMovies();
break;
case 1:
mMovies = gv.getAdventureMovies();
break;
case 2:
mMovies = gv.getAnimationMovies();
break;
}
m_Adapter.notifyDataSetChanged();
}
}
I don't what I'm doing wrong, I guess that the fragments are messed up, because when I press the second tab, data from the first tab is updated, and so on ...
Thanks!
Instead of using CollectionPageAdapter, I changed to use the TabsAdapter class shown in Android documentation of ViewPager and it works!
public class TabsAdapter extends FragmentPagerAdapter
implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
private final List<Fragment> fragments = new ArrayList<Fragment>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(FragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
#Override
public int getCount() {
return mTabs.size();
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
#Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
Fragment fr = Fragment.instantiate(mContext, info.clss.getName(), info.args);
//addFragment (fr, position);
return fr;
}
public void addFragment(Fragment f, int location) {
if (fragments.size() == 0)
fragments.add(f);
else
fragments.add(location, f);
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrollStateChanged(int state) {
}
#Override
public void onTabSelected(Tab tab, android.app.FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i=0; i<mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
updateDatasetMovies (i);
mViewPager.setCurrentItem(i);
}
}
}
#Override
public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) {
// TODO Auto-generated method stub
}
#Override
public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) {
// TODO Auto-generated method stub
}
public void updateDatasetMovies (int pos)
{
//Let's update the dataset for the selected genre
TabFragment fragment =
(TabFragment) ((FragmentActivity)mContext).getSupportFragmentManager().findFragmentByTag(
"android:switcher:"+R.id.pager+":"+pos);
//TabFragment fragment = (TabFragment) getItem(pos);
if(fragment != null) // could be null if not instantiated yet
{
if(fragment.getView() != null)
{
// no need to call if fragment's onDestroyView()
//has since been called.
fragment.updateDisplay(pos); // do what updates are required
}
}
}
}`
I agree with nirvik on this, however there is one cruciual improvement that should be made. This implementation has one flaw - when swiping to a next fragment the onPageSelected method is invoked, which in turn invokes onTabSelected method by calling mActionBar.setSelectedNavigationItem(position);. This causes a flicker in the animation.
This:
viewPager.setCurrentItem(i);
should be replaced by this:
if(i != viewPager.getCurrentItem()) {
viewPager.setCurrentItem(i);
}
resulting in a smooth transition.
You can try including the following code in your FragmentPagerAdapter and see if this addresses the issue.
public int getItemPosition(Object object) {
return POSITION_NONE;
}
You could also try using a FragmentStatePagerAdapter.

How to add a tag or id to a Fragment

This is my pager adapter.
public static class PagerAdapter extends FragmentPagerAdapter implements
ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public PagerAdapter(SherlockFragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getSupportActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
public int getCount() {
return mTabs.size();
}
public SherlockFragment getItem(int position) {
TabInfo info = mTabs.get(position);
return (SherlockFragment) Fragment.instantiate(mContext,
info.clss.getName(), info.args);
}
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
public void onPageScrollStateChanged(int state) {
}
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
Log.d("Tab position selected = ", "" + tab.getPosition());
// Log.v(TAG, "clicked");
Object tag = tab.getTag();
for (int i = 0; i < mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
How can i add a tag or an id to the fragments in each tab. So that i can access them later.
Thank You
You can use override for this method and apply your custom fragment,
#Override
public Fragment getItem(int position) {
if (position == 0)
fragment = new Fragment1();
else (position == 1)
fragment = new Fragment2();
return fragment;
}
and so on if else what ever your require implements and override for this method,
#SuppressLint("DefaultLocale")
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return ;
case 1:
return ;
}
return null;
}
try it out.

Getting the current fragment position using state pager of actionbarsherlock

I have a working state pager project using actionbarsherlock but I'm having trouble with getting the current fragment that was displayed. Is it possible to get the position of the current fragment?
Yes it is possible. If you are using a ViewPager you can do that :
_viewPager.getCurrentItem();
or that
_pageListener = new PageListener();
_viewPager.setOnPageChangeListener(_pageListener);
and keep trace of current page with something like that :
private int _currentPage;
private static class PageListener extends SimpleOnPageChangeListener{
public void onPageSelected(int position) {
Log.i(TAG, "page selected " + position);
_currentPage = position;
}
}
Or else you can easily do that with a TabAdapter like this :
public static class TabsAdapter extends FragmentPagerAdapter implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mActionBar = activity.getSupportActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
#Override
public int getCount() {
return mTabs.size();
}
#Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
((SherlockFragmentActivity) mContext).supportInvalidateOptionsMenu();
}
public void onPageScrollStateChanged(int state) {
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i = 0; i < mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
You only need to keep the current page with one/or two of the methods. For example in onTabSelected
hope it helps you
good luck

How to disable recreation of the first Fragment in FragmentPagerAdapter on tab Selected?

onCreateView for my first fragment in the FragmentPagerAdapter is not very quick.
So, changing curent tab to the first has a delay.
How to disable recreate first Fragment in FragmentPagerAdapter on tab Selected?
private class TabsAdapter extends FragmentPagerAdapter implements ViewPager.OnPageChangeListener, ActionBar.TabListener {
private final Context context;
private ActionBar bar;
private final ViewPager viewPager;
private final ArrayList<TabInfo> tabs = new ArrayList<TabInfo>();
final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
context = activity;
bar = activity.getSupportActionBar();
viewPager = pager;
viewPager.setAdapter(this);
viewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
tabs.add(info);
bar.addTab(tab);
notifyDataSetChanged();
}
#Override
public int getCount() {
return tabs.size();
}
#Override
public Fragment getItem(int position) {
TabInfo info = tabs.get(position);
Fragment fragment = Fragment.instantiate(context, info.clss.getName(), info.args);
return fragment;
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
#Override
public void onPageScrollStateChanged(int state) {}
#Override
public void onPageSelected(int position) {
bar.setSelectedNavigationItem(position);
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i = 0; i < tabs.size(); i++) {
if (tabs.get(i) == tag)
viewPager.setCurrentItem(i);
}
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {}
}
Right now i am stuck with the same problem.
when you are on a Tab:(n), only Tab:(n-1) and Tab:(n+1) will be alive in the memory, for memory usage optimization. Rest all Tabs will be destroyed, thats the reason why when you come back to the first Tab, its onCreateView is being called again.
Actually Tab:1's onCreateView will be called even if you click Tab:2 because its the neighbourhood Tab.
One solution i got is:
change the OffscreenPageLimit of the ViewPager. Its default value is 1
viewPager.setOffscreenPageLimit(total no of Tabs - 1);
This way all the Tabs will be alive even if its offScreen. But this is recommended only if you have decent no of Tabs(<=5)
If you have huge no.of Tabs, better use
FragmentStatePagerAdapter

Categories

Resources