I've been playing with the com.example.android.common/view/SlidingTabLayout examples, and have hit a minor issue. I know how to work around / resolve it but am trying to understand the issue.
I've created a little app with half a dozen tabs, that displays wot I want, and generally it behaves as expected, but if I RAPIDLY navigate between the tabs, by pressing the tab titles, then I hit the Back button a new tab title View is created and attached to mTabStrip in populateTabStrip(), resulting in a stack of tab titles. The issue only happens if the navigation is Rapid, hit the tab's in a leisurely manner and the issue doesn't crop up, so assuming it's garbage collection related, see below. Anyway was wondering if anyone can explain what is going on behind the scenes.
from SlidingTabBasicFragment.java:
private void createAdapters(View view){
Log.v(TAG, "createAdapters()");
try {
//TODO createAdapters() work out why the app's ghosting
ViewPager mViewPager = (ViewPager) view.findViewById(R.id.viewpager);
int currentItem = mViewPager.getCurrentItem();
SamplePagerAdapter testAdaptor = (SamplePagerAdapter)mViewPager.getAdapter();
if ( testAdaptor == null ) {
Log.v(TAG, "createAdapters() - new SamplePagerAdapter() to be added");
mViewPager.setAdapter(new SamplePagerAdapter());
}
mViewPager.setCurrentItem(currentItem);
SlidingTabLayout mSlidingTabLayout = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs);
mSlidingTabLayout.setViewPager(mViewPager);
rebuildViews = false;
} catch (NullPointerException e) {
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_LONG).show();
}
}
From the main Activity:
@Override
public void onNavigationDrawerItemSelected(int position, int lastPosition) {
Log.v(TAG, "onNavigationDrawerItemSelected - entered");
Intent intent;
String createdFileName;
// update the main content by replacing fragments
FragmentTransaction transaction = getFragmentManager().beginTransaction();
onSectionAttached(position + 1);
switch (position) {
case 0: // Main - Vitals
Log.v(TAG, "adding a 'vitalFrag' to the fragment stack");
transaction.replace(R.id.main_content_fragment, new SlidingTabsBasicFragment(), "vitalFrag").addToBackStack(null).commit();
break;
case 1: // Settings
...
@Override
public void onBackPressed(){
Log.v(TAG, "onBackPressed - entered");
// Catch back action and pops from backStack
// (if you called previously to addToBackStack() in your transaction)
if (getFragmentManager().getBackStackEntryCount() > 0){
// If Open, close the Navigation Drawer, as can be confusing if the Navigation
// Drawer shows a different Option / Fragment as selected, after the previous
// fragment has been restored
NavigationDrawerFragment mNavFrag = (NavigationDrawerFragment)
getFragmentManager().findFragmentById(R.id.navigation_drawer);
if (mNavFrag != null && mNavFrag.isVisible() && mNavFrag.isDrawerOpen()) {
mNavFrag.closeDrawer();
mClosedDrawer = true;
}
// Pull back the last fragment
getFragmentManager().popBackStack();
}
// Default action on back pressed
else super.onBackPressed();
}
@Override
public void onVitalChanged() {
Log.v(TAG, "onVitalChanged() entered");
requestBackup();
//TODO onVitalChanged() - finish - just invalidate the views
SlidingTabsBasicFragment fragment = (SlidingTabsBasicFragment) getFragmentManager().findFragmentByTag("vitalFrag");
if (fragment != null) {
//Log.v(TAG, "onVitalChanged() asking fragment to rebuild the Vital views");
//fragment.setRebuildViews();
Log.v(TAG, "onVitalChanged - replace the Results fragment");
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.main_content_fragment, new SlidingTabsBasicFragment(), "vitalFrag")
.addToBackStack(null)
.commitAllowingStateLoss();
}
}
And from one of the fragments:
....
@Override
public void onResume() {
Log.v(TAG, "onResume() - entered");
if (rebuildViews) {
invalidateViews(this.getView());
}
ActionBar mActionBar = getActivity().getActionBar();
if (mActionBar != null)
mActionBar.setTitle(R.string.action_history);
super.onResume();
}