1

I'm a very newbie with Android. I want to create an activity with 3 horizontal pages. Each page has a grid view. I use ViewPager to create pages and use GridView for each page. Following is the code

public class CategoryActivity extends ActionBarActivity {

    static final int NUM_ITEMS = 3;

    MyAdapter mAdapter;

    ViewPager mPager;

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

        getSupportActionBar().hide();

        mAdapter = new MyAdapter(this.getSupportFragmentManager());

        mPager = (ViewPager)findViewById(R.id.pager);
        mPager.setAdapter(mAdapter);

    }

    //MyAdapter is adapter for Pager
    public class MyAdapter extends FragmentPagerAdapter {

        ArrayList<ArrayListFragment> fragments;
        public MyAdapter(FragmentManager fm) {
            super(fm);

            fragments = new ArrayList<>();

            for (int i = 0; i < NUM_ITEMS; i++) {
                ArrayListFragment f = new ArrayListFragment();

                fragments.add(f);
            }
       }

        @Override
        public int getCount() {
            return NUM_ITEMS;
        }

        @Override
        public Fragment getItem(int position) {

            //For each page -> get fragment for that page
            ArrayListFragment f = fragments.get(position);

            return f;
        }
    }

    //Adapter for each grid view in each Page
    public class ImageAdapter extends BaseAdapter {
        private Context mContext;
        private View parentView;

        public ImageAdapter(Context c) {
            mContext = c;
        }

        public ImageAdapter(Context c, View aParentView) {
            mContext = c;
            parentView = aParentView;
        }

        public int getCount() {
            return mThumbIds.length;
        }

        public Object getItem(int position) {
            return null;
        }

        public long getItemId(int position) {
            return 0;
        }

        // create a new ImageView for each item referenced by the Adapter
        public View getView(int position, View convertView, ViewGroup parent)        {
            View itemView;
            if (convertView == null) {

                //I really config view for each item in grid view....
                //The problem is not here
                //..........
            }
            return itemView;
        }

        // references to our images
        private Integer[] mThumbIds = {
                R.drawable.images, R.drawable.images,
                R.drawable.images, R.drawable.images,
                R.drawable.images, R.drawable.images,
                R.drawable.images, R.drawable.images,
                R.drawable.images, R.drawable.images,
                R.drawable.images, R.drawable.images
        };
    }

    public class ArrayListFragment extends Fragment {

        /**
         * When creating, retrieve this instance's number from its arguments.
         */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }

        /**
         * The Fragment's UI is just a simple text view showing its
         * instance number.
         */
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            final View v = inflater.inflate(R.layout.fragment_pager_list, container, false);

            GridView gridview = (GridView) v.findViewById(R.id.categridview);

            ImageAdapter ia = new ImageAdapter(CategoryActivity.this, gridview);
            gridview.setAdapter(ia);

            return v;
        }


        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);

        }

    }
}

It works well in repo v7. But after I upgraded to repo v9, it crashes after starting with error

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: <my project process>, PID: 1901
                  java.lang.IllegalStateException: Fragment <my project package>.CategoryActivity.ArrayListFragment must be a public static class to be  properly recreated from instance state.
                      at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:435)
                      at android.support.v4.app.BackStackRecord.add(BackStackRecord.java:426)
                      at android.support.v4.app.FragmentPagerAdapter.instantiateItem(FragmentPagerAdapter.java:103)
                      at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:1006)
                      at android.support.v4.view.ViewPager.populate(ViewPager.java:1154)
                      at android.support.v4.view.ViewPager.populate(ViewPager.java:1088)
                      at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1614)
                      at android.view.View.measure(View.java:18788)
                      at android.widget.LinearLayout.measureVertical(LinearLayout.java:901)
                      at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
                      at android.view.View.measure(View.java:18788)
                      at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
                      at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
                      at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135)
                      at android.view.View.measure(View.java:18788)
                      at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
                      at android.support.v7.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:389)
                      at android.view.View.measure(View.java:18788)
                      at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
                      at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
                      at android.view.View.measure(View.java:18788)
                      at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
                      at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
                      at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
                      at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
                      at android.view.View.measure(View.java:18788)
                      at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
                      at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
                      at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2643)
                      at android.view.View.measure(View.java:18788)
                      at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2100)
                      at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1216)
                      at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1452)
                      at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
                      at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
                      at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
                      at android.view.Choreographer.doCallbacks(Choreographer.java:670)
                      at android.view.Choreographer.doFrame(Choreographer.java:606)
                      at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
                      at android.os.Handler.handleCallback(Handler.java:739)
                      at android.os.Handler.dispatchMessage(Handler.java:95)
                      at android.os.Looper.loop(Looper.java:148)
                      at android.app.ActivityThread.main(ActivityThread.java:5417)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
I/Process: Sending signal. PID: 1901 SIG: 9
Application terminated.

I search around a couple of days but can't find any help to fix it Someone has a quite similar problem at

Android IllegalStateException: Fragment null must be a public static class to be properly recreated from instance state

and

Fragment must be a public static class to be properly recreated from instance state

Why ArrayListFragment must be a public static class, I suppose each must have a separate fragment

What is the problem here, can anyone help me figure out

Community
  • 1
  • 1
Scofield Tran
  • 828
  • 1
  • 18
  • 30

1 Answers1

1

Is ArrayListFragment in the same java file as the CategoryActivity? If it true, static class means that an instance of ArrayListFragment can be created without creating an instance of CategoryActivity. So each class can have own instance of ArrayListFragment.

Viktor Dolgalyov
  • 274
  • 2
  • 12
  • Yes, all are in one java file. But I not quite understand, can you explain more clearly. What should I have do? By the way, I create an instance of CategoryActivity from another activity, just create an Intent for CategoryActivity and launch it, nothing special. And all code in class CategoryActivity are shown above, nothing more – Scofield Tran Oct 04 '16 at 15:30
  • Of course. Read about nested classes in java and about their instantiation rules. You should create separate java file for the ArrayListFragment(and other fragments) or declare your nested fragment classes as static. Here some useful links: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html http://stackoverflow.com/questions/15571010/fragment-inner-class-should-be-static – Viktor Dolgalyov Oct 05 '16 at 07:51
  • Thank Viktor Dolgalyov, I move ArrayListFragment to another Java file and it works. I should read more about it – Scofield Tran Oct 05 '16 at 16:25