Jonfor
Jonfor

Reputation: 139

getArguments() returns null

getArguments() returns the correct JSON string the first time OnCreateView() is called for Frag1 but not when I swipe to Frag2 and OnCreateView() for Frag1 is called again. Instead, the "JSON" argument is null.

Activity:

SparkleViewPagerLayout sparkleViewPagerLayout = (SparkleViewPagerLayout) 
findViewById(R.id.view_pager_layout);
FragmentManager fm = getSupportFragmentManager();
sparkleViewPagerLayout.getViewPager().setAdapter(new FragmentPagerAdapter(fm) {
        @Override
        public int getCount() {
            return 4;
        }

        @Override
        public Fragment getItem(int pos) {
            switch (pos) {
                case 0:
                    return Frag0.newInstance(json0);
                case 1:
                    return Frag1.newInstance(json1); // <--THE FAILING FRAGMENT
                case 2:
                    return Frag2.newInstance(json2);
                case 3:
                    return Frag3.newInstance(json3);
                default:
                    return Frag0.newInstance(json0);
            }
        }
    });

Fragment:

public class Frag1 extends Fragment {
private ArrayList<Thing> things;
private Gson gson = new Gson();

public static Frag1 newInstance(String json) {
    Bundle args = new Bundle();
    args.putString("JSON", json);
    args.putInt("background", R.drawable.img_thing_bg_blurred);
    Frag1 fragment = new Frag1();
    fragment.setArguments(args);

    return fragment;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.thing_detailed, parent, false);
    int background = getArguments().getInt("background");
    Util.setBackground(v, background, getContext());

    String json = getArguments().getString("JSON");
    things = gson.fromJson(json, new TypeToken<ArrayList<Thing>>() {
    }.getType());

    setUpThingOne(v);

    FragmentManager fm = getChildFragmentManager();
    Fragment listFragment = fm.findFragmentById(R.id.thingFragmentListContainer);
    // We removed the thing in position one, need to update the JSON to reflect this change.
    String jsonNew = gson.toJson(things);
    if (listFragment == null) {
        Bundle bundle = new Bundle();
        bundle.putString("THINGLIST", jsonNew);
        listFragment = new ThingListFragment();
        listFragment.setArguments(bundle);
        fm.beginTransaction()
                .add(R.id.ThingFragmentListContainer, listFragment)
                .commit();
    }

    return v;
}

    private void setUpThingOne(View v) {
        TextView name = (TextView) v.findViewById(R.id.thingName);
        TextView type = (TextView) v.findViewById(R.id.thingField);
        ImageView dollarImg = (ImageView) v.findViewById(R.id.thingPrice);
        ImageView bgImg = (ImageView) v.findViewById(R.id.thingBg);

        for (Thing thing : things) {
            if (thing.getPosition() == 1) {
                name.setText(thing.getName());
                type.setText(thing.getField());
                Util.setDollarImage(getContext(), dollarImg, thingSpot.getPrice());
                RequestUtil.getImage2(getContext(), thing.getImage_url(), bgImg);

                //Remove the #1 thing so that we can make a fragment list from the others.
                //things.remove(thing);
                break;
            }
        }
    }
}

Crash log:

01-28 13:43:08.117 31378-31378/com.test.test E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.test.test, PID: 31378
    java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.Iterator java.util.ArrayList.iterator()' on a null object reference
       at com.test.test.fragments.Frag1.setUpThingOne(Frag1.java:78)
       at com.test.test.fragments.Frag1.onCreateView(Frag1.java:48)
       at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
       at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
       at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
       at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:570)
       at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
       at android.support.v4.view.ViewPager.populate(ViewPager.java:1106)
       at android.support.v4.view.ViewPager.populate(ViewPager.java:952)
       at android.support.v4.view.ViewPager$3.run(ViewPager.java:251)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
       at android.view.Choreographer.doCallbacks(Choreographer.java:670)
       at android.view.Choreographer.doFrame(Choreographer.java:603)
       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)

Upvotes: 1

Views: 1593

Answers (2)

Jonfor
Jonfor

Reputation: 139

Well, ends up I was not very careful when I did some copy pasting. I thought it was weird that onCreateView() was being called for Frag1 when I was swiping to Frag2 and I realized I was creating a new Frag1 in Frag2 instead of Frag2...Many hours wasted on something that should have never happened!

Upvotes: 1

h2nghia
h2nghia

Reputation: 452

The view pager stores your fragments in memory. It can be that the method newInstance just runs for the first time the fragment is created. When it is not visible on screen, its onDestroyView() may be called then when it is visible again and the onCreateView() callback is called (newInstance will be never triggered). That explains why the arguments on onCreateView() are null. You call put log in all fragment callbacks to see the states of your fragment. Check Android for more detail on fragment life-cycle.

Upvotes: 0

Related Questions