Android Open Source - DynamicViewPager Dynamic Tab Fragment Pager Adapter






From Project

Back to project page DynamicViewPager.

License

The source code is released under:

Apache License

If you think the Android project DynamicViewPager listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package de.wackernagel.android.dynamicviewpager.adapter;
/*from ww  w  .j  av  a  2s.  c o m*/
import java.util.LinkedList;
import java.util.List;

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.Tab;
import android.support.v7.app.ActionBar.TabListener;
import android.view.ViewGroup;

public class DynamicTabFragmentPagerAdapter extends FragmentPagerAdapter {
  private final Context context;
  private final List<PageInfo> pages;
  private final ViewPager pager;
  private final ActionBar actionBar;
  private final ActionBar.TabListener tabListener;
  private final FragmentManager fragmentManager;
    
  public DynamicTabFragmentPagerAdapter( final Context context, final FragmentManager fm, final ViewPager pager, final ActionBar actionBar ) {
    super( fm );
    
    this.context = context;
    this.fragmentManager = fm;
    this.pages = new LinkedList<PageInfo>();
    this.pager = pager;
    this.actionBar = actionBar;
    this.tabListener = createTabListener();
    
    pager.setOnPageChangeListener( createPageChangeListener() );
    pager.setAdapter( this );
    
    actionBar.setNavigationMode( ActionBar.NAVIGATION_MODE_TABS );
  }
  
  /**
   * @return TabListener which update pager position to selected tab position.
   */
  private final TabListener createTabListener() {
    return new TabListener() {      
      @Override
      public void onTabSelected(Tab tab, FragmentTransaction ft) {
        if( pager.getCurrentItem() != tab.getPosition() ) {
          pager.setCurrentItem( tab.getPosition() );
        }        
      }
      
      @Override
      public void onTabUnselected(Tab tab, FragmentTransaction ft) {}
      
      @Override
      public void onTabReselected(Tab tab, FragmentTransaction ft) {}
    };
  }

  /**
   * @return OnPageChangeListener which update ActionBar tab position to selected pager position.
   */
  private final OnPageChangeListener createPageChangeListener() {
    return new ViewPager.SimpleOnPageChangeListener() {
      @Override
      public void onPageSelected(int position) {
        super.onPageSelected(position);
        if( actionBar.getSelectedNavigationIndex() != position ) {
          actionBar.setSelectedNavigationItem(position);
        }        
      }
    };
  }
  
  public void addPage( String title, Class<? extends Fragment> fragment ) {
    addPage( title, fragment, null );
  }

  public void addPage( String title, Class<? extends Fragment> fragment, Bundle arguments ) {
    if( fragment != null ) {      
      pages.add( new PageInfo( fragment, title, arguments ) );
      
      actionBar.addTab( actionBar.newTab().setText( title ).setTabListener( tabListener ) );      
      
      notifyDataSetChanged();
    }
  }
  
  public void removePage( int position ) {
    if( position >= 0 && position < pages.size() && pages.size() > 1 ) {
      
      pages.remove( position );
      
      // i don't know why but reset adapter to have no pager exception
      pager.setAdapter( this );
      notifyDataSetChanged();
      
      // remove tab after page was removed
      actionBar.removeTab(actionBar.getTabAt(position));
    }
  }
  
  public void replacePage( int position, String title, Class<? extends Fragment> fragment ) {
    replacePage( position, title, fragment );
  }

  public void replacePage( int position, String title, Class<? extends Fragment> fragment, Bundle arguments ) {
    if( position >= 0 && position < pages.size() ) {      
      pages.remove( position );
      pages.add( position, new PageInfo( fragment, title, arguments ) );
      
      actionBar.getTabAt( position ).setText( title );
      
      notifyDataSetChanged();
    }
  }

  @Override
  public int getItemPosition(Object object) {
    if( !pages.contains( (Fragment) object) ) {
      return POSITION_NONE;
    } else {
      return POSITION_UNCHANGED;
    }
  }

  @Override
  public long getItemId(int position) {
    return pages.get( position ).id;
  }

  @Override
  public Fragment getItem(int position) {
    if( position >= 0 && position < pages.size() ) {
      PageInfo page = pages.get( position );
      Fragment item = Fragment.instantiate(context, page.pageClass, page.arguments);
      return item;
    } else {
      return null;
    }
  }

  @Override
  public void destroyItem(ViewGroup container, int position, Object object) {
    super.destroyItem(container, position, object);
    
    // remove destroyed Fragment from FragmentManager
    if( !pages.contains( (Fragment) object ) ) {
      fragmentManager.beginTransaction().remove( (Fragment) object ).commit();
    }    
  }

  @Override
  public int getCount() {
    return pages.size();
  }
  
  /**
   * Load the Fragment instance from FragmentManager of given position.
   * 
   * @param position
   * @return  instance of Fragment at given position
   */
  public Fragment getFragmentInstance( int position ) {
    return fragmentManager.findFragmentByTag( buildTag( getItemId( position ) ) );
  }
  
  /**
   * @param itemId
   * @return build a unique tag of pager id, fragment id and a prefix.
   */
  private final String buildTag( long itemId ) {
    return "android:switcher:" + pager.getId() + ":" + itemId;
  }
  
  public class PageInfo
  {
    public final String pageClass;
    public final String title;
    public final Bundle arguments;
    public final long id;
    
    public PageInfo( final Class<? extends Fragment> clss, final String title, final Bundle arguments )
    {
      this.pageClass = clss.getName();
      this.title = title;
      this.arguments = arguments;
      
      // create a unique id for FragmentManager
      this.id = pageClass.hashCode() ^ title.hashCode() ^ arguments.hashCode();
    }
  }
}




Java Source Code List

de.wackernagel.android.dynamicviewpager.Lockable.java
de.wackernagel.android.dynamicviewpager.adapter.DynamicTabFragmentPagerAdapter.java
de.wackernagel.android.dynamicviewpager.view.LockableViewPager.java
de.wackernagel.dynamicviewpager.MainActivity.java
de.wackernagel.dynamicviewpager.SimpleFragment.java