6

This will be the last question I have about tabs, I promise :) (maybe) So from previous questions and try and error I have FragmentPagerAdapter called PagerAdapter which creates a few tabs and also gives me the ability to create new tabs dynamicly. The problem is that the new tabs will always get inserted to the RIGHT of my existing tabs:

(Picture: http://s7.directupload.net/file/d/3198/73dyzvzv_png.htm

I tried the following:

  1. Add a static entry of "null" that would be skipped when creating the intial set of tabs. Then later when creating "Temp Tab" I could override that entry to whatever fragment I desired. Gave me some strange IllegalSTateException...

  2. The thing I thought would work the best and actually really wanted to work badly: Instead of adding fragments with:

    private final List<Fragment> mFragments = new ArrayList<Fragment>();
    
    public void addFragment(Fragment fragment) {
        mFragments.add(fragment);
        notifyDataSetChanged();
    }
    

to use

mFragments.add(0, fragment);

But it gives an IllegalStateException with the message:

Can't change tag of fragment ChatFragment

When I try to add the temp fragment. Now, two questions:

  1. Is there a way around that fragment tab, can I take away all fragment tags for a moment and rebuild them all or something? Or

  2. Is there a much better and elegant way to do this? Or should I just redesign my UI so that the tab can be used to the right? :P

EDIT: Here some code: (I never wanna just post a Wall of death to people because it might scare them off :o )

FragmentPagerAdapter:

public class PagerAdapter extends FragmentPagerAdapter {

  private Context mContext;

  public PagerAdapter(FragmentManager fm, Context context) {
    super(fm);
    mContext = context;
  }

  private final List<Fragment> mFragments = new ArrayList<Fragment>();
  public void addFragment(Fragment fragment) {
    mFragments.add(fragment);
    notifyDataSetChanged();
  }

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

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

  @Override
  public String getPageTitle(int position) {

    switch (position) {
    case 0:
      return mContext.getString(R.string.tab_title_chats);
    case 1:
      return mContext.getString(R.string.tab_title_contacts);
    case 2:
      return mContext.getString(R.string.tab_title_create);
    }
    return "WOOPS";

  }

}

MainActivty:

public class LaunchActivity extends FragmentActivity implements ActionBar.TabListener {

  private PagerAdapter mAdapter;
  private FragmentManager man;
  private ViewPager mViewPager;
  private ActionBar actionBar;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout_container);

    // Set up the action bar.
    actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    // Layout stuff
    mViewPager = (ViewPager) findViewById(R.id.masterViewPager);

    // Creating the mAdapter and initializing the mViewPager
    man = getSupportFragmentManager();
    mAdapter = new PagerAdapter(man, getApplicationContext());
    mViewPager.setAdapter(mAdapter);

    for (int i = 0; i < 2; i++) {
      makeFragments(i);
      System.out.println("Baking tasty fragment instances...nom nom nom");
    }

    // Called when tab changes
    mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
      @Override
      public void onPageSelected(int position) {
        actionBar.setSelectedNavigationItem(position);
      }
    });

    for (int i = 0; i < mAdapter.getCount(); i++) {
      System.out.println("Working...");

      actionBar.addTab(actionBar.newTab().setText(mAdapter.getPageTitle(i)).setTabListener(this));
    }

  }

  // Add fragment instances to ArrayList depending on their future position on the ActionBar
  private void makeFragments(int i) {

    if (i == 0) {
      mAdapter.addFragment(ChatFragment.getInstance());

    }
    else if (i == 1) {
      mAdapter.addFragment(ContactFragment.getInstance());
    }
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.layout_container, menu);
    return true;

  }

  @Override
  public void onTabSelected(Tab tab, FragmentTransaction ft) {
    mViewPager.setCurrentItem(tab.getPosition());

  }

  public void addTab(int i) {
    mAdapter.addFragment(ComposeFragment.getInstance());
    System.out.println("Created new Fragment, now adding it as a tab");
    actionBar.addTab(actionBar.newTab().setText(mAdapter.getPageTitle(i)).setTabListener(this));
    System.out.println("Added it as a tab. Hurray");

  }

  /** IGNORE BELOW **/

  @Override
  public void onTabUnselected(Tab tab, FragmentTransaction ft) {
  }

  @Override
  public void onTabReselected(Tab tab, FragmentTransaction ft) {
  }



}

Stacktrace:

    03-18 18:32:29.274: E/AndroidRuntime(26435): FATAL EXCEPTION: main
    03-18 18:32:29.274: E/AndroidRuntime(26435): java.lang.IllegalStateException: Can't change tag of fragment ChatFragment{41492428 #1 id=0x7f070004 android:switcher:2131165188:1}: was android:switcher:2131165188:1 now android:switcher:2131165188:2
    03-18 18:32:29.274: E/AndroidRuntime(26435):    at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:398)
    03-18 18:32:29.274: E/AndroidRuntime(26435):    at android.support.v4.app.BackStackRecord.add(BackStackRecord.java:389)
    03-18 18:32:29.274: E/AndroidRuntime(26435):    at android.support.v4.app.FragmentPagerAdapter.instantiateItem(FragmentPagerAdapter.java:99)
    03-18 18:32:29.274: E/AndroidRuntime(26435):    at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:801)
    03-18 18:32:29.274: E/AndroidRuntime(26435):    at android.support.v4.view.ViewPager.populate(ViewPager.java:992)
    03-18 18:32:29.274: E/AndroidRuntime(26435):    at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:523)
    03-18 18:32:29.274: E/AndroidRuntime(26435):    at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:495)
    03-18 18:32:29.274: E/AndroidRuntime(26435):    at android.support.v4.view.ViewPager.dataSetChanged(ViewPager.java:875)
    03-18 18:32:29.274: E/AndroidRuntime(26435):    at android.support.v4.view.ViewPager$PagerObserver.onChanged(ViewPager.java:2690)
    03-18 18:32:29.274: E/AndroidRuntime(26435):    at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
    03-18 18:32:29.274: E/AndroidRuntime(26435):    at android.support.v4.view.PagerAdapter.notifyDataSetChanged(PagerAdapter.java:276)
    03-18 18:32:29.274: E/AndroidRuntime(26435):    at com.package.subpackage.components.PagerAdapter.addFragment(PagerAdapter.java:25)
    03-18 18:32:29.274: E/AndroidRuntime(26435):    at com.package.subpackage.someapp.core.LaunchActivity.addTab(LaunchActivity.java:116)
    03-18 18:32:29.274: E/AndroidRuntime(26435):    at com.

com.package.subpackage.fragments.full.ChatFragment$1.onClick(ChatFragment.java:51)
03-18 18:32:29.274: E/AndroidRuntime(26435):    at android.view.View.performClick(View.java:4204)
03-18 18:32:29.274: E/AndroidRuntime(26435):    at android.view.View$PerformClick.run(View.java:17355)
03-18 18:32:29.274: E/AndroidRuntime(26435):    at android.os.Handler.handleCallback(Handler.java:725)
03-18 18:32:29.274: E/AndroidRuntime(26435):    at android.os.Handler.dispatchMessage(Handler.java:92)
03-18 18:32:29.274: E/AndroidRuntime(26435):    at android.os.Looper.loop(Looper.java:137)
03-18 18:32:29.274: E/AndroidRuntime(26435):    at android.app.ActivityThread.main(ActivityThread.java:5041)
03-18 18:32:29.274: E/AndroidRuntime(26435):    at java.lang.reflect.Method.invokeNative(Native Method)
03-18 18:32:29.274: E/AndroidRuntime(26435):    at java.lang.reflect.Method.invoke(Method.java:511)
03-18 18:32:29.274: E/AndroidRuntime(26435):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
03-18 18:32:29.274: E/AndroidRuntime(26435):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
03-18 18:32:29.274: E/AndroidRuntime(26435):    at dalvik.system.NativeStart.main(Native Method)
paulgavrikov
  • 1,883
  • 3
  • 29
  • 51
AreusAstarte
  • 1,958
  • 2
  • 17
  • 29
  • post your entire code and if possible post the entire stack trace – Triode Mar 18 '13 at 17:21
  • Done. Added the MainActivity (which holds all the tab management) and the PagerAdapter – AreusAstarte Mar 18 '13 at 17:33
  • in the addFragment function change this line of code to mFragments.add(fragment); to mFragments.add(0, fragment); this. – Triode Mar 18 '13 at 17:37
  • Well, if you ha read my post carefully, that's exactly what I'm doing. That's where I get the IllegalStateException and get the StackTrace thrown...with the way I just displayed it works however Tabs are being displayed on the RIGHT side of the other tabs, not the left that I would want – AreusAstarte Mar 18 '13 at 17:39
  • instead of notifyDataSetChanged(); Just use notifyDataSetInvalidated() – Triode Mar 18 '13 at 17:42
  • I don't seem to be able to call invalidateDataSet() from that class. Neither can I find some proper documentation about the method. Would you be so kind to give me some pointers? – AreusAstarte Mar 18 '13 at 17:46
  • see the edited comment it is notifyDataSetInvalidated(). – Triode Mar 18 '13 at 17:47
  • The method notifyDataSetInvalidated() is undefined for the type PagerAdapter with PagerAdapter extends FragmentPagerAdapter. Do I need to extend the BaseAdapter for that or some other interface? Because with the BaseAdapter all the Fragment-oriented methods no longer work. obv – AreusAstarte Mar 18 '13 at 17:53
  • no you can't use the SimpleAdpater with the fragmentpager – Triode Mar 18 '13 at 18:03

1 Answers1

0

I could achieve this by overriding onPageSelected method of OnPageChangeListener. Consider you have three pages in this order A<->B<->C. To goal is to reach C if we scroll right from A and similarly to reach A if we scroll left from C.

To do this, define your to have 5 pages (3+2), and organize the pages as follows:

C<->A<->B<->C<->A

Now in the onPageSelected method, check and if position if 0, change it to 3 (getCount()-2) and if position is 4 (getCount()-1), change it to 1. Make sure to this like can help u .

Thanks

Akash Singh
  • 5,171
  • 2
  • 26
  • 55