1

I am trying to send two strings via a bundle to the next fragment but the app crashes even before I get to the first fragment.

I get this error in the second fragment:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.android.guessit, PID: 22360
    java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference
        at com.example.android.guessit.GameFlow.FragmentAnswer1.onCreateView(FragmentAnswer1.java:125)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2600)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:881)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1238)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1303)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
        at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2079)
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1869)
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
        at androidx.fragment.app.FragmentManagerImpl.execSingleAction(FragmentManagerImpl.java:1696)
        at androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:299)
        at androidx.fragment.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:259)
        at androidx.viewpager.widget.ViewPager.populate(ViewPager.java:1244)
        at androidx.viewpager.widget.ViewPager.setCurrentItemInternal(ViewPager.java:669)
        at androidx.viewpager.widget.ViewPager.setCurrentItemInternal(ViewPager.java:631)
        at androidx.viewpager.widget.ViewPager.setCurrentItem(ViewPager.java:612)
        at com.example.android.guessit.GameFlow.GameActivity.setViewPager(GameActivity.java:152)
        at com.example.android.guessit.GameFlow.FragmentOneCategory$6.onClick(FragmentOneCategory.java:190)
        at android.view.View.performClick(View.java:7352)
        at android.view.View.performClickInternal(View.java:7318)
        at android.view.View.access$3200(View.java:846)
        at android.view.View$PerformClick.run(View.java:27800)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7050)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)

I know that this means that the string value that I am trying to receive in the second fragment means that there is no value for that string but I don't know where the problem here is because the strings I am trying to send are not null.

This is the code I am using for the bundle in the first fragment (using this in onCreatView):

FragmentAnswer1 frag1 = new FragmentAnswer1();
Bundle args = new Bundle();
args.putString("question_1", question);
args.putString("answer_1", answer);
frag1.setArguments(args);

getFragmentManager().beginTransaction().add(R.id.container, frag1).commit(); // there is a message that says that "beginTransaction" may produce a nullPointer

Here is the code to receive the strings in the second fragment (currently also in onCreateView)

question = getArguments().getString("question_1"); // error is in this line
answer = getArguments().getString("answer_1");
question1.setText(question);
rightAnswer.setText(answer);

I already tried to move the above code into the onStartmethod but I still get the same error. I also tried using this solution but its not working for me. I did not find any other solution or method on how to resolve the problem.

Please let me know if you need more informations. Any help is much appreciated!

Kaiser
  • 606
  • 8
  • 22
  • Have you check this one : https://stackoverflow.com/a/40949016/7666442 – AskNilesh Jan 08 '20 at 11:10
  • you are getting `nullpointerexception` ? – Rahul sharma Jan 08 '20 at 11:13
  • @NileshRathod Rathod When I am using ```replace``` instead of ```add``` I am getting a blank fragment, not the fragment I want – Kaiser Jan 08 '20 at 11:21
  • @frankenstein yes it is a ```nullPointerException``` – Kaiser Jan 08 '20 at 11:22
  • The code itself here is correct. The problem lies elsewhere. For example, if you are inside a fragment, then maybe you should be using `childFragmentManager`. Please show more of the stack trace. – EpicPandaForce Jan 08 '20 at 11:22
  • @EpicPandaForce I edit my question with the full error message – Kaiser Jan 08 '20 at 11:34
  • @Kaiser i added my answer check that out. – Rahul sharma Jan 08 '20 at 11:37
  • 1
    @EpicPandaForce you are right. kindly edit question and add complete code what you are doing in onClick Event. Basically complete code block of setting argument. – Shadow Droid Jan 08 '20 at 11:38
  • Do you have ViewPager? And in FirstFragment you are trying to set argument for SecondFragment? – Shadow Droid Jan 08 '20 at 11:39
  • Yes i am setting up a ViewPager in the Activity that holds the Fragments. And yes I am trying to set arguments for the second fragment in the first fragment – Kaiser Jan 08 '20 at 11:42
  • This not the correct way to pass data between fragments in ViewPager. First understand viewpager has already loaded those fragments so when you try to add fragment it just changes the current item. – Shadow Droid Jan 08 '20 at 11:47
  • What is the correct way to pass data in ViewPager? – Kaiser Jan 08 '20 at 11:49
  • You can implement custom listener in ViewPager Adapter where you just set current item and pass data to that fragment. Kindly do not use add or replace. – Shadow Droid Jan 08 '20 at 11:53
  • probably your code would have worked in onViewCreated()...need to check...cannot gurantee. – Shadow Droid Jan 08 '20 at 11:58
  • You must add `GameActivity.setViewPager(GameActivity.java:152)` and `FragmentOneCategory$6.onClick(FragmentOneCategory.java:190)` to the question in order to have a complete understanding of the error cause – EpicPandaForce Jan 08 '20 at 11:58

4 Answers4

1

I have now found the correct way to send data from one Fragment to another while having a ViewPager. We have to use a ViewModel.

First we have to create a ViewModel, in this case our goal is to send a String from Fragment 1 to Fragment 2. Here is the code for the ViewModel with Getter and Setter method for the String:

public class ViewModelString extends ViewModel {

    private MutableLiveData<String> mString = new MutableLiveData<>();

    public MutableLiveData<String> getmString() {
        return mString;
    }

    public void setmString(MutableLiveData<String> mString) {
        this.mString = mString;
    }

}

Then in Fragment 1 from where we want to sent the string we need to first initialize the ViewModel in onCreate.

public class Fragment1 extends Fragment {

private ViewModelString viewModel;

public Fragment1() {
        // Required empty public constructor
    }

    public static Fragment1 newInstance() {
        return new Fragment1();
    }

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

        // initialize ViewModel here
        viewModel = ViewModelProviders.of(requireActivity()).get(ViewModelString.class);
    }

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

String hello = "hello";

viewModel.setmString(hello);

}
}

Then in the second Fragment we also have to first initialize the viewModel and then create an observer. Here we then take the String that is stored in the ViewModel and set a TextView to its value:

public class Fragment2 extends Fragment {

private ViewModelString viewModel;

public Fragment2() {
        // Required empty public constructor
    }

    public static Fragment2 newInstance() {
        return new Fragment2();
    }

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

        // initialize ViewModel here
        viewModel = ViewModelProviders.of(requireActivity()).get(ViewModelString.class);
    }

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

TextView textView = findViewById(R.id.yourTextViewId);

        // Gets the string
        viewModel.getmString().observe(requireActivity(), new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                textView.setText(s);

            }
        });

}
...
}

I hope this helps anyone! Please feel free to edit my post.

Kaiser
  • 606
  • 8
  • 22
0

Use Bundle to send String:

//Put the value
 Bundle args = new Bundle();
args.putString("YourKey", "YourValue");
YourFragmentName ldf = new YourFragmentName ();
ldf.setArguments(args);

//Inflate the fragment
 getActivity().getSupportFragmentManager().beginTransaction().add(R.id.container, ldf).commit();

In onCreateView of the new Fragment:

//Retrieve the value
Bundle bundle = this.getArguments();

if (bundle  != null) {
    String value = bundle.getString("YourKey");
}
Mayur Rajvir
  • 140
  • 5
  • This is exactly what I am using but that is not working for me – Kaiser Jan 08 '20 at 11:16
  • @Kaiser can you please check updated answer..?? In my case it's working. – Mayur Rajvir Jan 08 '20 at 11:20
  • With that I am not getting an error anymore but I am still not receiving the string values in the second fragment – Kaiser Jan 08 '20 at 11:28
  • Can you please debug and check in First Fragment what value is getting stored and check in another Fragment what value are you getting. @Kaiser – Mayur Rajvir Jan 08 '20 at 11:35
  • This ```args.putString("answer_1", answer);```in the first fragment has a value, also the question, but in the second fragment I don't get a value for them – Kaiser Jan 08 '20 at 11:40
  • Have checked the id's of textview in second fragment where you are setting the value. @Kaiser – Mayur Rajvir Jan 08 '20 at 11:46
0

Use a Bundle. Here's an example:

Fragment fragment = new Fragment();
Bundle bundle = new Bundle();
bundle.putInt("Key", "value");
fragment.setArguments(bundle);
fragmentManager.beginTransaction().replace(R.id.container, frag1).commit()

Bundle has put methods for lots of data types. See this

Then in your Fragment, retrieve the data in onCreate() method like:

Bundle bundle = this.getArguments();
if (bundle != null) {
        int myInt = bundle.getString(Key);
}
Nensi Kasundra
  • 1,980
  • 6
  • 21
  • 34
0

try this.

     var fragment: MainFragment =MainFragment()
    val args = Bundle()
    args.putString("question_1", "My question")
    args.putString("answer_1", "My answer")
    fragment.setArguments(args)

    fragmentManager.beginTransaction().add(R.id.fragment_content, fragment).commit()
Rahul sharma
  • 1,492
  • 12
  • 26