1

I have an application running on an embedded system with 4 tabs in a SectionsPagerAdapter and in the Fragment of each tab I have code that updates the display every 0.5 seconds via a timer.

I find that when I create 4 tabs, the first 2 are created and 3 and 4 are only created if I scroll to the right which is expected.

The issue for me is that after the view for each tab is created and the timer is started, the timer fires and the calls to update the views gets processed even if the tab is not visible.

I am trying to find a way to know if the tab is visible or not and if it's hidden, I simply skip the re-drawing of the views. Only when the tab is visible do I do the updates.

I have tried using isShown() and hasWindowFocus() from the the view that getView() returns but they always return true;

I've also tried to use onPause and onResume for each fragment but they only get called when I move to the 2rd tab from it. Eg, on tab1, move to tab2, not called, moved to tab3, onPause() called.

For now I have used onTabSelected() to store the current tab in my singleton class that all the fragments have access to the system data from. When I create the fragment, I pass in the tab position.

BUT , how can I check for this view being visible in a more elegant way?

1 Answers1

2

You can check if the Fragment you want to update is selected in an OnPageListener attached to your ViewPager. In the listener you can check if the page you want to update your timer on is selected. Here is an example:

SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

    @Override
    public void onPageSelected(int page) {

        /*If the page is the page you want to update your timer on, enable it.*/
        if ( page == myTimerPageId ){
            FragmentManager fragmentManager = getSupportFragmentManager();
            Fragment timerFragment = fragmentManager.findFragmentByTag("android:switcher:" + mViewPager.getId() + ":" + myTimerPageId);
            timerFragment.startTimer();
        }
        /*If it is not the page you update your timer on, disable it.*/
        else{
            FragmentManager fragmentManager = getSupportFragmentManager();
            Fragment timerFragment = fragmentManager.findFragmentByTag("android:switcher:" + mViewPager.getId() + ":" + myTimerPageId);
            timerFragment.stopTimer();
        }

    }


    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) {}

    @Override
    public void onPageScrollStateChanged(int arg0) {}

});

You have to get the Fragment through the FragmentManager and then do whatever you want to that Fragment, implement startTimer() or something. myTimerPageId must be the identifier of the page where you are incrementing your timer. The findFragmentByTag part is stolen from this answer. The OnPageChangeListener part is grabbed from here.

As a side note, the ViewPager has an setOffscreenPageLimit that sets how many pages beside the active one that is kept in memory. This can be minimum 1, though, so it is not possible to use this together with Fragment.onPause to achieve what is asked here. If this could be of use in another sitatuation, take a look here.

Community
  • 1
  • 1
Krøllebølle
  • 2,878
  • 6
  • 54
  • 79