androidcommonsware-cwacandroid-pageradaptercommonsware

App crash after adding another item - cwac-pager



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.


Solution

  • 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.