0

I'm working on an app I need to send some data from ListFragment to ItemFragment. I use bundle but I get nullpointerexception. I should mention that i'm a newbie and this is my first app. so let me know if what I did is wrong or confusing. Here are my codes

ListFragment.java

            if (child != null && mGestureDetector.onTouchEvent(motionEvent)) {
                int position = recyclerView.getChildLayoutPosition(child);
                selectedItem = mItems.get(position);
                itemId = mItems.get(position).getId();
                openFragment(new ItemFragment(), "MyApp");
                ItemFragment if = new ItemFragment();
                Bundle bundle = new Bundle();
                bundle.putLong("selectedId", itemId);
                if.setArguments(bundle);
}
            return false;
        }

ItemFragment.java

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {


    Bundle bundledData = this.getArguments();
    selectedId = bundledData.getLong("selectedId");//here is the line 105 in logcat

    return mRootView;
}

Logcat

java.lang.NullPointerException
at me.myapp.fragments.ItemFragment.onCreateView(ItemFragment.java:105)
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$1.run(FragmentManager.java:517)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)

---Added---

For some reason, I still get the same error when I tried the answers here except for nguyen's. From what I understand in nguyen's code, I use this

ListFragment.java

private long itemId;

if (child != null && mGestureDetector.onTouchEvent(motionEvent)) {
                int position = recyclerView.getChildLayoutPosition(child);
                selectedItem = mItems.get(position);
                itemId = mItems.get(position).getId();
                Bundle bundle = new Bundle();
                bundle.putLong("selectedId", itemId);
                ItemFragment itemFrag = ItemFragment.newInstance(bundle);
                openFragment(new ItemFragment(), "Update Item");
                Toast.makeText(getActivity(), "id = " + itemId, Toast.LENGTH_SHORT).show();

ItemFragment.java

private long selId;

public static ItemFragment newInstance(Bundle bundle) {
    ItemFragment frag = new ItemFragment();
    frag.setArguments(bundle);
    return frag;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    if (getArguments() != null) {
         selId = getArguments().getLong("selectedId");
    }
    makeToast(""+selId);

return mRootView;
}

I didn't get any error with these codes. The toast in ListFragment does shows the correct value but the toast in ItemFragment always returns 0. what am i missing here??

Joan Z
  • 43
  • 1
  • 9

5 Answers5

1

To put bundle in Fragment you should use a static funtion newInstance(Bundle bundle) in your ItemFragment:

public static ItemFragment newInstance(Bundle bundle) {
    ItemFragment myFragment = new ItemFragment();

    myFragment.setArguments(bundle);

    return myFragment;
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    Bundle bundle = getArguments();
    // DO SOMETHING

    return super.onCreateView(inflater, container, savedInstanceState);
}

And use it you call:

Bundle bundle = new Bundle();
//put data in bundle
ItemFragment  itemfrag = ItemFragment.newInstance(bundle);
1

In ItemFragment, you should write in this way

 Bundle bundledData = this.getArguments();
        if (getArguments() != null) {
          selectedId = bundledData.getLong("selectedId");
        }

And you may add Toast inside the if block to check whether the selectedId get displayed or not.

Edited

ItemFragment.java

 private long selId;


     @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View edit_details = inflater.inflate(R.layout.edit_staff_list, container, false);
            Bundle bundle = this.getArguments();
            if (getArguments() != null) {
               selId = bundle.getLong("selectedId");
                Toast.makeText(getActivity(), selId, Toast.LENGTH_LONG).show();

            }
John Joe
  • 12,412
  • 16
  • 70
  • 135
  • Strange. Yesterday I tried, I still get the same error but I tried today, seems like the error is gone now =/ but no matter what I click, the value is always 0. any idea why? thanks anyway – Joan Z Jan 23 '16 at 06:58
  • Have you checked `itemId` in **ListFragment** ? What value get displayed? – John Joe Jan 23 '16 at 07:04
  • Yeap. I put a toast in ListFragment too, it shows the correct value. It's just the toast in ItemFragment that always shows 0 – Joan Z Jan 23 '16 at 07:06
0

You are creating two instances of the same fragment, setting the arguments on the second one, and showing the first one which doesn't have any arguments. Hence, the NullPointerException when you try to extract argument in onCreateView.

...
openFragment(new ItemFragment(), "MyApp"); // Show first fragment
ItemFragment if = new ItemFragment(); // Instantiate second fragment
Bundle bundle = new Bundle();
bundle.putLong("selectedId", itemId);
if.setArguments(bundle); // arguments go to the second one | The one which is never even displayed to the user.
...
Clinkz
  • 716
  • 5
  • 18
muratgu
  • 7,241
  • 3
  • 24
  • 26
  • sorry, I forgot to explain what I was trying to do. when user click on an item in listfragment, it will open ItemFragment. So I need to pass the id of selected item in ListFragment to ItemFragment so I can do some other stuffs in ItemFragment. How do I do that? – Joan Z Jan 22 '16 at 04:43
  • @JoanZ : Use the following code inside the onItemClickListener : ItemFragment itemFragment = new ItemFragment(); Bundle bundle = new Bundle(); bundle.putLong("selectedId", lngItemId); itemFragment.setArguments(bundle); getFragmentManager().beginTransaction().add(idOfLayout, itemFragment, strFragmentTag); On onCreateView : long lngSelectedId = getArguments().getLong("selectedId", 0); //Always return a default value in case long does not exist in arguments. Almost everyone has written a similar code. I'm not able to understand what is going wrong when you say, "Its still not working". – Clinkz Jan 22 '16 at 05:00
  • i have no idea why i still get the same error with most of the codes here =/ anyway, I edited my post and posted the new one I tried. I managed to get rid of the error but the value always returns 0. can you take a look at it thanks – Joan Z Jan 22 '16 at 08:01
0

Try edit your code in listFragment to this.

if (child != null && mGestureDetector.onTouchEvent(motionEvent)) {
    int position = recyclerView.getChildLayoutPosition(child);    
    selectedItem = mItems.get(position);        
    itemId = mItems.get(position).getId();

    ItemFragment itemFragment = new ItemFragment();
    Bundle bundle = new Bundle();
    bundle.putLong("selectedId", itemId);
    itemFragment.setArguments(bundle);

    openFragment(itemFragment, "MyApp");
}

return false;

The problem with your code is you passed in a new instance of ItemFragment to openFragment() function instead of the one you created and added with a bundle.

kopikaokao
  • 500
  • 7
  • 13
0

After hours messing around with the code, trial and error, tried different codes, nguyen's code and the code here https://stackoverflow.com/a/16036693/5563156 gives me the idea. these codes seems to get the job done

ListFragment.java

mRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
        @Override
        public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
            View child = recyclerView.findChildViewUnder(motionEvent.getX(), motionEvent.getY());

            if (child != null && mGestureDetector.onTouchEvent(motionEvent)) {
                int position = recyclerView.getChildLayoutPosition(child);
                selectedItem = mItems.get(position);
                itemId = mItems.get(position).getId();
                //pass selected item's ID to Main Activity
                Intent i = new Intent(getActivity(), MainActivity.class);
                i.putExtra("selectedId", itemId);
                startActivity(i);
                Toast.makeText(getActivity(), "id = " + itemId, Toast.LENGTH_SHORT).show();

            }
            return false;
        }

In MainActivity's OnCreate

if(savedInstanceState == null){
        //receives selected item's ID passed from ListFragment
        Intent intent = getIntent();
        long selId = intent.getLongExtra("selectedId", 0);

         if (selId > 0) {
             //send the selected item ID to ItemFragment
             Bundle bundle = new Bundle();
             bundle.putLong("selectedId", 0);
             ItemFragment frag = new ItemFragment();
         openFragment(ItemFragment.newInstance(selId), "Update Item");
         frag.setArguments(bundle);
         }}

ItemFragment.java

public static ItemFragment newInstance(long selId) {
    ItemFragment fragment = new ItemFragment();

    if (selId > 0) {
        Bundle bundle = new Bundle();
        bundle.putLong("selectedId", selId);
        fragment.setArguments(bundle);
    }
    return fragment;
}

In ItemFragment's OnCreateView

Bundle args = getArguments();
    if (args != null && args.containsKey("selectedId")) {
        selId = args.getLong("selectedId");
    }

Thanks to everyone who posted their codes! Appreciate the help.

Community
  • 1
  • 1
Joan Z
  • 43
  • 1
  • 9