1


I'm having trouble with adding another page to the cwac-pager's ArrayPagerAdapter (v4). I had to use that library because I wasn't able to add a new tab dynamically using the system PagerAdapter.
MainActivity.java:

public class MainActivity extends AppCompatActivity implements TabLayout.OnTabSelectedListener {

    private ViewPager viewPager;
    private ArrayPagerAdapter pagerAdapter;
    private TabLayout tabLayout;

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

        setSupportActionBar((Toolbar) findViewById(R.id.app_toolbar));

        tabLayout = findViewById(R.id.tab_layout);
        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

        viewPager = findViewById(R.id.pager);
        pagerAdapter = new CustomPagerAdapter(getSupportFragmentManager(), new ArrayList<PageDescriptor>());
        viewPager.setAdapter(pagerAdapter);
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
        tabLayout.addOnTabSelectedListener(this);
    }

    @Override
    public void onStart() {
        super.onStart();
        pagerAdapter.add(new TestPageDescriptor());
        tabLayout.addTab(tabLayout.newTab().setText("Hello"));
        // Uncomment the following lines to make the app crash
        pagerAdapter.add(new TestPageDescriptor()); // CRASH
        tabLayout.addTab(tabLayout.newTab().setText("Hello2"));
    }

    @Override
    public void onStop() {
        super.onStop();
        // Remove all the tabs (required in my main application, not in this test)
        tabLayout.removeAllTabs();
        for (int i = 0; i < pagerAdapter.getCount(); i++) {
            pagerAdapter.remove(i);
        }
    }

    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        viewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {

    }

    @Override
    public void onTabReselected(TabLayout.Tab tab) {

    }

    private class CustomPagerAdapter extends ArrayPagerAdapter<Fragment> {

        CustomPagerAdapter(FragmentManager fragmentManager, List<PageDescriptor> descriptors) {
            super(fragmentManager, descriptors);
        }

        @Override
        protected Fragment createFragment(PageDescriptor desc) {
            return new TestFragment();
        }
    }

    private class TestPageDescriptor extends SimplePageDescriptor {

        TestPageDescriptor() {
            super("Test","TestHey");
        }
    }
}

TestFragment.java:

public class TestFragment extends Fragment {

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.test_frag, container, false);
    }
}

activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="me.test.myapplication.MainActivity"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/app_toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:title="@string/app_name" />

    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:elevation="4dp"
        android:minHeight="?attr/actionBarSize"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="fill_parent" />
</LinearLayout>

test_frag.xml: just a LinearLayout with a View, no matter which.

In MainActivity.java see the comments I added in onStart(): if you run the app with just one tab (last two lines of the method commented), the activity will start correctly. However, if you add another tab by uncommenting the lines, the app will crash immediately. What am I doing wrong?
Thanks

Edit: logcat

I/Process: Sending signal. PID: 3877 SIG: 9
Application terminated.

No exceptions, no errors.

  • `the app will crash`, okay.. what is the error stack trace that is printed to LogCat? – Matt Clark Feb 04 '18 at 15:54
  • What is `TestPageDescriptor`? Seems like there might be something in there that causes a crash on the creation of the second instance. – Matt Clark Feb 04 '18 at 15:57
  • Unfortunately, NO logcat. Just "Application terminated." – marcocipriani01 Feb 04 '18 at 15:57
  • Sorry, no errors printed to LogCat when you see Android kill the app? Can you [edit] your post to show the exact LogCat output when the crash happens. – Matt Clark Feb 04 '18 at 15:59
  • See at the bottom of MainActivity, there you'll see TestPageDescriptor. It contains all the information needed to create a new Fragment in createFragment(PageDescriptor). In this case TestPageDescriptor is useless, but I'll need it in my main app. – marcocipriani01 Feb 04 '18 at 15:59
  • 2
    Gotcha. In your constructor you call `super("Test","TestHey");` - Now, I have not used this library before but I can only make assumptions - can you try changing these values for the second object? The framework may not handle two Pages with the same tag. – Matt Clark Feb 04 '18 at 16:01
  • 1
    I actually went and [found the source](https://github.com/commonsguy/cwac-pager/blob/2e5a3f52e2268602e38433009618e0dc02c36f00/pager/src/com/commonsware/cwac/pager/v4/ArrayPagerAdapter.java#L286) - and it looks like the behavior is as mentioned in my previous comment. Pages must all have unique tags. – Matt Clark Feb 04 '18 at 16:03
  • Thanks, it worked! – marcocipriani01 Feb 04 '18 at 16:04

1 Answers1

1

The fragment tags need to be unique, as is covered in the library documentation. So, as Matt Clark pointed out, you need to use different tags for your different pages.

Note that you do not need to create your own subclass of SimplePageDescriptor, at least in the code from your question. You could just use SimplePageDescriptor directly.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thanks! I know, I can use SimplePageDescriptor. I was using that subclass because of my main app's implementation of PageDescriptor. – marcocipriani01 Feb 04 '18 at 20:21