9

I receive data from a web service that is parsed into an object in the Application class, this object which in my case is a Report class contains a list of Tabs that should populate the ViewPager. So this Report is stored in the currentReport parameter in the Application class.

Each tab should be a page in the ViewPager. So for the first time when I receive the data and parse it, all works perfectly and the View Pager is populated with the correct data and presents it.

My problem starts when I want to get a new Report from the server and refresh the ViewPager with the new data that was parsed into the currentReport parameter.

My ViewPager is swipe-able and has tabs navigation, So when I try to re-instantiate the ViewPager with the new Report I see the right amount of tabs added to the tabHost. for some reason the fragments of the new report overlaping the fragment of the previos one. So if the number of tabs in the new report is bigger the tabs in the previous report then I can see the tabs from the previous report in addition to part of the new ones (if for example in the first report I had one tab, and in the new one I have 3 then I see the one fragment from the previous and the last 2 from the next one).

I have started my development from this tutorial and added smoe code to it: http://thepseudocoder.wordpress.com/2011/10/13/android-tabs-viewpager-swipe-able-tabs-ftw/

This is my Tab Activity code:

public class TabsViewPagerFragmentActivity extends FragmentActivity implements    ViewPager.OnPageChangeListener, TabHost.OnTabChangeListener 
{
static final String TAG = TabsViewPagerFragmentActivity.class.getSimpleName();
private TabHost mTabHost;
private ViewPager mViewPager;
private HashMap<String, TabInfo> mapTabInfo;
public ViewPagerAdapter mPagerAdapter;
private TextView tvReportName, tvTabTitle;
private Button bBackToParameters;
private Dialog progressDialog;
private SGRaportManagerAppObj application;
private int numberOfTabs = 0;
private Display display;
public static final int POPUP_MARGIN = 6;
LeftSideMenu leftSideMenu;

public void NotifyTabActivityViewPagerAdapter()
{
    mPagerAdapter.notifyDataSetChanged();
}

public ViewPagerAdapter getTabActivityViewPagerAdapter()
{
    return mPagerAdapter;
}

public ViewPager getTabActivityViewPager()
{
    return mViewPager;
}

public void setCurrentTabTitle (String title)
{
    tvTabTitle.setText(title);
    Log.d(TAG, "set tab title from activity: "+title);
}


/**
* Maintains extrinsic info of a tab's construct
*/
private class TabInfo 
{
    private String tag;
    private Class<?> clss;
    private Bundle args;
    private Fragment fragment;

    TabInfo(String tag, Class<?> clazz, Bundle args) 
    {
        this.tag = tag;
        this.clss = clazz;
        this.args = args;
    }
}

/**
 * A simple factory that returns dummy views to the Tabhost
 */
class TabFactory implements TabContentFactory {

    private final Context mContext;

    /**
     * @param context
     */
    public TabFactory(Context context) {
        mContext = context;
    }

    /** (non-Javadoc)
     * @see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String)
     */
    public View createTabContent(String tag) {
        View v = new View(mContext);
        v.setMinimumWidth(0);
        v.setMinimumHeight(0);
        return v;
    }
}

/** (non-Javadoc)
 * @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle)
*/
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    application = SGRaportManagerAppObj.getInstance();
    display = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
    // Inflate the layout
    setContentView(R.layout.tabs_screen_activity_layout);
    tvTabTitle = (TextView) findViewById(R.id.tvTabName);
    tvReportName = (TextView)findViewById(R.id.tvReportName);
    tvReportName.setText(application.currentReport.getName()+ " - ");
    bBackToParameters = (Button) findViewById(R.id.bBackToParameters);
    leftSideMenu = (LeftSideMenu) findViewById(R.id.leftSideMenu);
    applyOnClickListenerToLeftSideMenu();

    findViewById(R.id.showLeftMenuButton).setOnClickListener(new View.OnClickListener() 
    {
        @Override
        public void onClick(View v) 
        {               
            Display d = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
            int width = d.getWidth();

            View panel = findViewById(R.id.leftSideMenu);
            View appPanel = findViewById(R.id.appLayout);
            if (panel.getVisibility() == View.GONE){
                appPanel.setLayoutParams(new LinearLayout.LayoutParams(width, LayoutParams.FILL_PARENT));
                panel.setVisibility(View.VISIBLE);
                applyOnClickListenerToLeftSideMenu();
            }else{
                ToggleButton button = (ToggleButton) findViewById(R.id.showLeftMenuButton);
                button.setChecked(false);
                panel.setVisibility(View.GONE);
            }
        }
    });

    // Initialise the TabHost
    progressDialog = DialogUtils.createProgressDialog(this, this.getString(R.string.populating_view_pager));
    progressDialog.show();

    if (SGRaportManagerAppObj.getInstance().parametersRepository.getParametersRepository().size() == 0)
    {
        bBackToParameters.setText(R.string.back_to_report_list);
    }
    this.initialiseTabHost(savedInstanceState);

    if (savedInstanceState != null) {
        mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab")); //set the tab as per the saved state
    }
    // Intialise ViewPager
    this.intialiseViewPager();
    progressDialog.dismiss();
}

 /** (non-Javadoc)
 * @see android.support.v4.app.FragmentActivity#onSaveInstanceState(android.os.Bundle)
 */
protected void onSaveInstanceState(Bundle outState) {
    outState.putString("tab", mTabHost.getCurrentTabTag()); //save the tab selected
    super.onSaveInstanceState(outState);
}

/**
 * Initialise ViewPager
 */
public void intialiseViewPager() 
{

    List<Fragment> fragments = new Vector<Fragment>();

  // TabInfo tabInfo = null;

    if (application.getCurrentDataSource().equals(DataSource.SSRS))
    {
        numberOfTabs = application.currentReport.getTabsList().size();
    }
    else if (application.getCurrentDataSource().equals(DataSource.SGRDL))
    {
        numberOfTabs = application.currentReport.getODTabsList().size();
        Log.d(TAG, "CURRENT REPORT FROM VIEW PAGER: "+ application.currentReport.toString());
    }   

    Log.d(TAG,"Current Tabs number from TabsViewPager activity: " +numberOfTabs);

    if (application.getCurrentDataSource().equals(DataSource.SSRS))
    {
         for (int i = 0; i < numberOfTabs; i++)     
         {
            Tab tempTab = application.currentReport.getTabsList().get(i);
            if (tempTab.getTabTemplateId() == 7)
            {
                GridFragment gridFragment = new GridFragment(tempTab);
                fragments.add(gridFragment);
            }
            else  if (tempTab.getTabTemplateId() == 8)
            {
                NewChartFragment chartFragment = new NewChartFragment(tempTab, this);
                fragments.add(chartFragment);
            }
         }
    }
    else if (application.getCurrentDataSource().equals(DataSource.SGRDL))
    {
         for (int i = 0; i < numberOfTabs; i++)     
         {
            ODTab tempTab = application.currentReport.getODTabsList().get(i);
            if (tempTab.getTabType().equals(ODGrid.XML_GRID_ELEMENT))
            {
                GridFragment gridFragment = GridFragment.newInstance(tempTab.getTabId());
                fragments.add(gridFragment);
            }
            else  if (tempTab.getTabType().equals(ODChart.XML_CHART_ELEMENT))
            {
                NewChartFragment chartFragment = NewChartFragment.newInstance(tempTab.getTabId());
                fragments.add(chartFragment);
            }
         }
    }   

    Log.d(TAG, "Current report fragments set to adapter: "+fragments.toString());
   /*
    if (this.mPagerAdapter == null)
    {
        this.mPagerAdapter  = new ViewPagerAdapter(super.getSupportFragmentManager(), fragments);
    }
    else
    {
        this.mPagerAdapter.removeAllFragments();
        this.mPagerAdapter.addFragmentsListToAdapter(fragments);
    }
    */
    this.mPagerAdapter  = new ViewPagerAdapter(super.getSupportFragmentManager(), fragments);
    this.mViewPager = (ViewPager)super.findViewById(R.id.pager);
//    this.mViewPager.setAdapter(null);
    this.mViewPager.setAdapter(this.mPagerAdapter);
    this.mViewPager.setOffscreenPageLimit(0);
    this.mViewPager.setOnPageChangeListener(this);
    Log.d(TAG, "Adapter initialized!");
}

/**
 * Initialise the Tab Host
 */
public void initialiseTabHost(Bundle args) {
    mTabHost = (TabHost)findViewById(android.R.id.tabhost);

    /*
    //new edit
    if (mTabHost.getChildCount() > 0)
    {
        mTabHost.removeAllViews();
    }
    */

    mTabHost.setup();
    TabInfo tabInfo = null;
    mapTabInfo = new HashMap<String, TabsViewPagerFragmentActivity.TabInfo>();
    if (args != null)
    {}
    else
    {
        if (application.getCurrentDataSource().equals(DataSource.SSRS))
        {
            int numberOfTabs = application.currentReport.getTabsList().size();
            for (int i = 0; i < numberOfTabs; i++)      
            {
                Tab tempTab = application.currentReport.getTabsList().get(i);
                if (tempTab.getTabTemplateId() == 7)
                {
                    //GridFragment gridFragment = new GridFragment(tempTab);
                    TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab "+String.valueOf(i)).setIndicator("Tab "+String.valueOf(i)), ( tabInfo = new TabInfo("Tab "+String.valueOf(i), GridFragment.class, args)));
                    this.mapTabInfo.put(tabInfo.tag, tabInfo);
                }
                else  if (tempTab.getTabTemplateId() == 8)
                {
                    TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab "+String.valueOf(i)).setIndicator("Tab "+String.valueOf(i)), ( tabInfo = new TabInfo("Tab "+String.valueOf(i), NewChartFragment.class, args)));
                    this.mapTabInfo.put(tabInfo.tag, tabInfo);
                }
            }
        }

        else if (application.getCurrentDataSource().equals(DataSource.SGRDL))
        {
            int numberOfTabs = application.currentReport.getODTabsList().size();
            for (int i = 0; i < numberOfTabs; i++)      
            {
                ODTab tempTab = application.currentReport.getODTabsList().get(i);
            //  Log.d(TAG,"Crashed Tab type: "+ tempTab.getTabType());
                if (tempTab.getTabType().equals(ODGrid.XML_GRID_ELEMENT))
                {
                    //GridFragment gridFragment = new GridFragment(tempTab);
                    TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab "+String.valueOf(i)).setIndicator("Tab "+String.valueOf(i)), ( tabInfo = new TabInfo("Tab "+String.valueOf(i), GridFragment.class, args)));
                    this.mapTabInfo.put(tabInfo.tag, tabInfo);
                }
                else  if (tempTab.getTabType().equals(ODChart.XML_CHART_ELEMENT))
                {
                    TabsViewPagerFragmentActivity.AddTab(this, this.mTabHost, this.mTabHost.newTabSpec("Tab "+String.valueOf(i)).setIndicator("Tab "+String.valueOf(i)), ( tabInfo = new TabInfo("Tab "+String.valueOf(i), NewChartFragment.class, args)));
                    this.mapTabInfo.put(tabInfo.tag, tabInfo);
                }
            }
        }
    }
    // Default to first tab
    //this.onTabChanged("Tab1");
    //
    mTabHost.setOnTabChangedListener(this);
}

/**
 * Add Tab content to the Tabhost
 * @param activity
 * @param tabHost
 * @param tabSpec
 * @param clss
 * @param args
 */
private static void AddTab(TabsViewPagerFragmentActivity activity, TabHost tabHost, TabHost.TabSpec tabSpec, TabInfo tabInfo) 
{
    // Attach a Tab view factory to the spec       
    ImageView indicator = new ImageView(activity.getBaseContext());
    indicator.setPadding(10, 10, 10, 10);
    indicator.setImageResource(R.drawable.tab_select_icon_selector);
    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
    lp.setMargins(10, 10, 10, 10);
    indicator.setLayoutParams(lp);
    tabSpec.setIndicator(indicator); 
    tabSpec.setContent(activity.new TabFactory(activity));
    tabHost.addTab(tabSpec);
}

/** (non-Javadoc)
 * @see android.widget.TabHost.OnTabChangeListener#onTabChanged(java.lang.String)
 */
public void onTabChanged(String tag) {
    //TabInfo newTab = this.mapTabInfo.get(tag);
    int pos = this.mTabHost.getCurrentTab();
    this.mViewPager.setCurrentItem(pos);
}

/* (non-Javadoc)
 * @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrolled(int, float, int)
 */
@Override
public void onPageScrolled(int position, float positionOffset,
        int positionOffsetPixels) {
    // TODO Auto-generated method stub

}

/* (non-Javadoc)
 * @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageSelected(int)
 */
@Override
public void onPageSelected(int position) {
    // TODO Auto-generated method stub
    this.mTabHost.setCurrentTab(position);
}


/* (non-Javadoc)
 * @see android.support.v4.view.ViewPager.OnPageChangeListener#onPageScrollStateChanged(int)
 */
@Override
public void onPageScrollStateChanged(int state) {
    // TODO Auto-generated method stub

}

and this is my Adapter code:

public class ViewPagerAdapter extends FragmentPagerAdapter 
{
private List<Fragment> fragments;

/**
 * @param fm
 * @param fragments
 */
public ViewPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
    super(fm);
    this.fragments = fragments;
}

/* (non-Javadoc)
 * @see android.support.v4.app.FragmentPagerAdapter#getItem(int)
 */

@Override
public Fragment getItem(int position) {
    return this.fragments.get(position);
}

/* (non-Javadoc)
 * @see android.support.v4.view.PagerAdapter#getCount()
 */

@Override
public int getCount() {
    return this.fragments.size();
}

@Override
public int getItemPosition(Object object) {
    return POSITION_NONE;
} 

My AsyncTask that parses the data and updated the ViewPager:

public class ParseSGRDLReportDataAsyncTask extends AsyncTask<String, Object, Report>{

static final String TAG = ParseSGRDLReportDataAsyncTask.class.getSimpleName();
private Activity activity;  
private Exception exception;
private ResponseHandler responseHandler = new ResponseHandler();
private SGRaportManagerAppObj application;
private Dialog progressDialog;

public ParseSGRDLReportDataAsyncTask(LoginScrActivity activity) {
    super();
    this.activity = activity;
}

public ParseSGRDLReportDataAsyncTask(Activity currentActivity) {
    super();
    this.activity = currentActivity;
}

public void onPreExecute() {
    application = SGRaportManagerAppObj.getInstance();
    progressDialog = DialogUtils.createProgressDialog(activity, activity.getString(R.string.parse_data_dialog_message));
    progressDialog.show();
}

@Override
protected Report doInBackground(String... params) {

    String ReportDataString = params[0];
    try{
        return DataAccessManager.parseSGRDLReportData(ReportDataString);            
    }
    catch (Exception e) {
        exception = e;
        return null;
    }
}

@Override
public void onPostExecute(Report result) {
    progressDialog.dismiss();

    if (exception == null) 
    {
        if (activity.getClass() == TabsViewPagerFragmentActivity.class)
        {
            application.currentReport = result;
            Log.d(TAG, "Current report parsed is: "+result);

            ((TabsViewPagerFragmentActivity)activity).intialiseViewPager();

            ((TabsViewPagerFragmentActivity)activity).initialiseTabHost(null);

            ((TabsViewPagerFragmentActivity)activity).NotifyTabActivityViewPagerAdapter();

            }
        else
        {
            responseHandler.handleProcessSGRDLReportDataResult(result, activity);       
        }
    }
    else {
        processException();
    }
}

private void processException() {
    Toast.makeText(activity,   activity.getString(R.string.error_when_parsing_data), 3000).show();
}
}

Answer: Following @Luksprog advice for all people that stumble on the same problem this is the final result that works for me, in the AsyncTask I needed to added this:

if (activity.getClass() == TabsViewPagerFragmentActivity.class)
{
                TabsViewPagerFragmentActivity tempActivity = ((TabsViewPagerFragmentActivity)activity);
                application.currentReport = result;
                Log.d(TAG, "Current report parsed is: "+result);
                List<Fragment> frags =  tempActivity.getTabActivityViewPagerAdapter().getFragments(); // getter method in your adapter
                FragmentTransaction ft = tempActivity.getSupportFragmentManager().beginTransaction();
                for (int i = 0; i < frags.size(); i++) 
                {
                    ft.remove(frags.get(i));
                }
                ft.commit(); 
                tempActivity.intialiseViewPager();
                tempActivity.getTabHost().getTabWidget().removeAllViews();
                tempActivity.initialiseTabHost(null);
                tempActivity.NotifyTabActivityViewPagerAdapter();
}

When the main two point are to remove the previous added fragments from the FragmentManager/SupportFragmentManager using a FragmentTransaction to show the correct set of fragments in the ViewPager and to remove all view from the TabWidget before adding new ones.

Emil Adz
  • 40,709
  • 36
  • 140
  • 187
  • And where in your code do you change the content of the `ViewPager`(after a new data retrieval)? – user Jun 06 '13 at 15:01
  • @Luksprog, added the AsyncTask code that parses the data and is in charge to refresh the ViewPager. – Emil Adz Jun 06 '13 at 15:05
  • Try to first set the `ViewPager`'s adapter to `null` and then do the normal stuff you would do(initializing the `ViewPager`); – user Jun 06 '13 at 15:35
  • @Luksprog, I have added this line: ((TabsViewPagerFragmentActivity)activity).getTabActivityViewPager().setAdapter(null); before the initialization in the AsyncTask, but the result stays the same. – Emil Adz Jun 06 '13 at 16:20
  • @Emil Adz i was facing the same problem from last two days but today i found the solution when you will load the new data before that create new adapter and set it to the viewpager after that add your views and don't forget to call .notifydatasetchanged.it will solve your problem and if not let me know i will explain it with sample code tomorrow. – TheFlash Jun 14 '13 at 16:49
  • @Pratik, thanks for your help, It could be really helpful if you could provide some code snippet. – Emil Adz Jun 14 '13 at 20:09

3 Answers3

6

I'm not sure you solved this, if yes ignore my answer. The link provided by Neron T is important(more important the advices given there to not reference the fragments of the adapter outside).

When you set the adapter the second time with the new data you'll keep seeing the old fragments because of the way the FragmentPagerAdapter is implemented. When you set the adapter again the adapter will first run the destroyItem() method in which its fragment will be detached from the ViewPager. Next the adapter will run the instantiateItem() method. In this method a check will be performed against the FragmentManager to see if any of the previous fragments aren't still available. This check will find the old fragments(at least for the old positions, that's why you get new fragments for position which weren't in the previous situation, there weren't any fragment at that moment) because they are simply detached from the ViewPager(but still available in the FragmentManager through findFragmentByTag()). If a fragment isn't found in the FragmentManager only then the getItem() method will be called, retrieving a fragment from your list.

You should revise your code to remove the list reference to those fragments, there are other ways to retrieve the fragments from the ViewPager(not quite ideal either). As a quick fix, you could try to manually remove the old fragments from the FragmentManager(just before setting the new adapter) to force the ViewPager.instantiateItem() method to always call getItem():

if (activity.getClass() == TabsViewPagerFragmentActivity.class) {
        application.currentReport = result;
        Log.d(TAG, "Current report parsed is: "+result);
        ListFragment<Fragment> frags = ((ViewPagerAdapter)mViewPager.getAdapter()).getFragments(); // getter method in your adapter
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    for (int i = 0; i < mOldTmp.size(); i++) {
    ft.remove(frags.get(i));
    }
    ft.commit(); 
        ((TabsViewPagerFragmentActivity)activity).intialiseViewPager();

        ((TabsViewPagerFragmentActivity)activity).initialiseTabHost(null);

        ((TabsViewPagerFragmentActivity)activity).NotifyTabActivityViewPagerAdapter();

        }

This is not tested so try it and see if it works.

Community
  • 1
  • 1
user
  • 86,916
  • 18
  • 197
  • 190
  • Thanks @Luksprog for your explanation and code snippet. this did the job for me. The only real problem that is left for me is that the TabHost is not getting updated with the right amount of tabs, it adds the the number of tabs from previous report to the current number. So it never delete the previous one. Do you know where do I make a mistake with the tabHost implementation? how to remove the old tabs in the tabHost? – Emil Adz Jun 15 '13 at 12:26
  • @EmilAdz So after you set the adapter the second time you see the old number of tabs + the number of tabs for the new adapter? – user Jun 15 '13 at 12:31
  • right. if in the first report I had 1 fragment and in the second I had 3. I see 4 tabs in the tabhost but only the first 3 are working for the seocnd report. the forth one doesn't do anything. – Emil Adz Jun 15 '13 at 12:33
  • my guess is that in the initialiseTabHost method I always run AddTab method without removing the old set of tabs. the problem is that I have no idea how is the old set should be removed. – Emil Adz Jun 15 '13 at 12:35
  • @EmilAdz I'm not sure, but try adding `mTabHost.getTabWidget().removeAllViews()` before initializing the adapter the second time before the line `((TabsViewPagerFragmentActivity)activity).initialiseTabHost(null);`. – user Jun 15 '13 at 12:35
  • You were right, this sets the right amount of views in the tabhost. Sorry to be a nag, You answer is the right answer and did the job for me with the ViewPager and the TabHost the only problem I have is that if I switch to a report with one tabhost. this tabhost is not selected. Do you know why this may be? – Emil Adz Jun 15 '13 at 12:42
  • @EmilAdz I'm not sure I understand the last issue. Do you mean switching between reports with different tab numbers(like switching from a report that has 5 tabs to one report that has a single tab)? Also, *is not selected* - the tab itself or do your refer to something else? – user Jun 15 '13 at 12:54
  • Basically my tabs represented by a selector which has two states. a selected state and not selected state. Usually when I open a report which has one tab, this tab in the tab host is represented using the selected state image. But now when I switch from one report to another one with one tab this tab is in the not selected state image. If I open a report with more then one tab (say 3) non of those tabs in the tab host has the selected state (one should be as it shown in the viewPager) if i choose another tab, then this tab in the tab host gets selected. I hope I was clear enough this time. – Emil Adz Jun 15 '13 at 13:00
  • @EmilAdz When you re-set the adapter its `OnPageChangeListener` will not be called and your `TabHost` doesn't know what to select. I'm assuming that the selection doesn't exist only until a tab gets selected for the first time. So you may need to manually reset the `ViewPager` and `TabHost` `mViewPager.setCurrentItem(0);mtabHost.setCurrentTab(0);` when you reset the adapter. – user Jun 15 '13 at 13:16
  • Tried to add this: ((TabsViewPagerFragmentActivity)activity).getTabHost().setCurrentTab(0); ((TabsViewPagerFragmentActivity)activity).getTabActivityViewPager().setCurrentItem(0); after resetting the the viewpager but this didn't do the trick for me. – Emil Adz Jun 15 '13 at 13:34
  • @EmilAdz Strange. How about if instead of `((TabsViewPagerFragmentActivity)activity).getTabHost().setCurrentTab(0);` you use `((TabsViewPagerFragmentActivity)activity).getTabHost().getTabWidget().getChildAt(0).setSelected(true);` – user Jun 15 '13 at 15:01
  • Well this does selected the first tab in the tabHost as I wanted. But now for some reason if I have more then one tab and I try to selected the second one, the first one doesn't get un-selected. Only if I press the first tab and switch to another one, only then it's gets un-selected. – Emil Adz Jun 15 '13 at 15:12
  • do you have any idea why this might happen? – Emil Adz Jun 16 '13 at 07:07
  • 1
    @EmilAdz I thought about the problem but I must admit I don't know why it happens. After you set the adapter(and before anything like `setCurrentTab()`) have you used `tabhost.getCurrentTab()` to see if one of the tabs is actually selected(and which one). I doubt it will work but try invalidating the TabHost after you set the adapter the second time(with `invalidate()`). – user Jun 16 '13 at 10:42
  • I will try it out and let you know. – Emil Adz Jun 16 '13 at 10:46
  • I have checked the invalidate option, as you expected it's not working. Still thank you very much for you help, I will keep looking for a solution. – Emil Adz Jun 16 '13 at 12:27
  • when i refresh the viewpagers data, first two view pagers are not refresh and other view pager data is changing. please help me – kartheeki j Oct 08 '15 at 08:10
  • @kartheekij Please post another question with all the details of your problem, code, behavior etc. – user Oct 08 '15 at 09:19
  • http://stackoverflow.com/questions/33012056/view-pager-first-and-second-fragment-data-is-not-updating-when-data-changed-in-a – kartheeki j Oct 08 '15 at 09:41
  • hi @Luksprog,your answer is really let me understand alot and it worked for me.But i still wonder that my recyclerview still update the data but not my TextView.its really make me confuse about it. – shadow Oct 24 '19 at 07:52
4

There are 2 solutions for this issue:

Solution 1 - the easy one See here: https://stackoverflow.com/a/13467232/444324

Basically you need to add this code to your viewpager adapter:

@Override
public int getItemPosition(Object object){
    return PagerAdapter.POSITION_NONE;
}

Solution 2 - the recommended one is well explained here: https://stackoverflow.com/a/8024557/444324

Community
  • 1
  • 1
Lior Iluz
  • 26,213
  • 16
  • 65
  • 114
  • You can see that solution 1 is already implemented in the code. Solution 2 is more of an explanation on how to use tag with ViewPagerAdapter and it doesn't fit my needs. – Emil Adz Jun 09 '13 at 09:44
1

I am going to post some of my code so that you will get some idea.

adapter initialization and set it to the view-pager.

vfPageContainer = (ViewPager)findViewById(R.id.vfPageContainer);
mAdapter = new TestFragmentAdapter(this,getSupportFragmentManager()); 
vfPageContainer.setAdapter(mAdapter);

each time new data comes and i call below method:

updateUi() method

private void updateUi()
{   
    for(int i=0 ; i < alDataPages.size() ; i++)
    {
        mAdapter.addFragment(TestFragment.newInstance(this));
    }

    mAdapter.notifyDataSetChanged();
}

In TestFragmentAdapter class there r methods for add and clear the fragments from view-pager.

TestFragmentAdapter class

class TestFragmentAdapter extends FragmentStatePagerAdapter {

    private Context context;

    private ArrayList<Fragment> views = new ArrayList<Fragment>();

    public TestFragmentAdapter(Context context,FragmentManager fm)
    {
        super(fm);

        this.context = context;

        views = new ArrayList<Fragment>();
    }

    @Override
    public Fragment getItem(int position)
    {
        return views.get(position);
    }

    public void addFragment (Fragment v)
    {
        views.add(v);
    }

    public void clear()
    {

        for(int i = 0 ; i < views.size() ; i++)
        {
            views.clear();
        }

    }

    @Override
    public int getCount() 
    {
        return views.size();
    }


}

TestFragment class

public final static class TestFragment extends Fragment {


    private Context context;

    public void setContext(Context c)
    {
        context = c;
    }

    public static TestFragment newInstance(Context context)
    {
        TestFragment f = new TestFragment();

        f.setContext(context);

        return f;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
    {
        WebView webView_viewpage = new WebView(context);

        return webView_viewpage;
    }


}

so when new data comes before that i call the below code. I am removing all the views from adapter and create new 1 and set it to the view-pager every time.You should also try this in you code it should work.

 mAdapter.clear(); // previously it was not working so i created new adapter and set it to the viewpager.
 mAdapter = new TestFragmentAdapter(this,getSupportFragmentManager()); 
 vfPageContainer.setAdapter(mAdapter);

hope this help to you and you will find solution.

TheFlash
  • 5,997
  • 4
  • 41
  • 46