2

I have a MainActivity (MA) running several fragments, which do not talk to each other but communicate to the MA via the 'onClick' android mechanism. Driven by a spinner choice and an 'onClick' button press, we arrive in the RetrievePatientRecord method of the MA.

I carry out a database call to get the chosen db record (as per the commented line) and then test to see if there is an existingPatient fragment present into which I intend to put the database record's various fields as its essentially a form. With a not found, 'null' condition, I instantiate a new instance of a ExistingPatientFg fragment. However when I attempt to use the existingPatient reference via a setter in the ExistPatientFg fragment to set the 'Title' field value the program falls over with a NPE !

I have tried to 'get the fragment address' using commented out line … getFragmentManager().findFragmentById(R.id….) but interestingly using android studio's code completion facility the only R.id. object it will offer is the 'fragment_container' which though it compiles, it falls over on this line of code if I leave it in.

So I'm a bit stumped. I've read through most of the other S/O answers in this fragment/MainActivity/edit text field, subject area but haven't been able to get a solution which can help me, so I'm after some assistance here. (also it may be relevant that my activity_main.xml layout file is using a FrameLayout layout with its id as 'fragment_container')

   public void RetrievePatientRecord(View view) {
//   do database query to get record before displaying in patient record fragment
             this.patientID = findPatientRecordFg.patientID;
        Log.d(DEBUGTAG, " ---->>>>> retrieve this record L 404 with ID =  " + findPatientRecordFg.patientID);

// db query for existing patient's records
          findPatientRecordFg.db.getPatientRecords(patientID);

// populate patientdetails fragment fields and re display patientdetails fragment.

        if (existingPatient != null) {

            populatePatientDetails_fgWithCurrentValues();
            trans = getFragmentManager().beginTransaction();
            trans.replace(R.id.fragment_container, existingPatient);
            trans.addToBackStack(null);
            trans.commit();
        }else
        if (existingPatient == null){

            existingPatient = new ExistingPatientFg();
          // ExistingPatientFg existingPatient = (ExistingPatientFg)getFragmentManager().findFragmentById(R.id.fragment_container);
            cTitle      = findPatientRecordFg.db.geteTitle();

            Log.d(DEBUGTAG, " ######## -->>>>> reached just before setTitleField L 424 with value Title  =  "+ cTitle);
            existingPatient.setTitleField(cTitle);

            //populatePatientDetails_fgWithCurrentValues();
            trans = getFragmentManager().beginTransaction();
            trans.replace(R.id.fragment_container, existingPatient);
            trans.addToBackStack(null);
            trans.commit();
        }
    }

the fragment's java code is :-

public class ExistingPatientFg extends Fragment {
public ButtonPlus btn;
public ButtonPlus analysisBtn;


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


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.patientdetails_fg, container, false);
    return view;
}

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

    EditText editText = (EditText)getView().findViewById(R.id.bannerText);
    editText.setText("Existing Patient");

    btn = (ButtonPlus)getActivity().findViewById(R.id.Goto_Scanning_Page);

    analysisBtn = (ButtonPlus)getView().findViewById(R.id.Analysis);
    btn.setEnabled(true);

}


public void setTitleField(String string){
    EditText et = (EditText)getView().findViewById(R.id.Title);
    et.setText(string);
}

2 Answers2

0

You can either find the fragment by tag that you supply when adding the fragment:

getFragmentManager().beginTransaction().replace(R.id.fragment_container, existingPatient, "Your Tag Here");

and than find it by tag:

getFragmentManager().findFragmentByTag("Your Tag Here")

Or, if you still want to find by ID - it should be the one that is returned by: fragment.getID(); it should be either the container of the fragment or the top layout in the fragment I'm not sure. (So you can check for debugging after adding the fragment

if fragment.getID()==R.id.container
A-_-S
  • 680
  • 5
  • 21
0

I suspect that the null pointer exception is not that you don't have a reference to the fragment, but that you are calling setTitleField before the fragment view has been inflated so the edit text field doesn't exist yet.

Try moving setTitleField to after the trans.commit or better yet pass the title to the fragment as an extra argument.

existingPatient = new ExistingPatientFg();
Bundle bundle = new Bundle();
bundle.putString("title",cTitle);
existingPatient.setArguments(bundle);                 
trans = getFragmentManager().beginTransaction();
trans.replace(R.id.fragment_container, existingPatient);
trans.addToBackStack(null);
trans.commit();

And use the following inthe Fragment's onCreateView to get the title

String cTitle = getArguments().getString("title");

See How to pass a variable from Activity to Fragment, and pass it back?

Community
  • 1
  • 1
QuantumTiger
  • 970
  • 1
  • 10
  • 22
  • Hi QuantumTiger and thank you very much for your solution. You were absolutely right, once I'd followed the 'Bundle' solution, using the 'getArguments()' the NPE disappeared. However I had to add the getArguments()…. line of code to my Fragment's onActivityCreated(..) method as opposed to your suggestion of the onCreateView() method before it worked, which I don't really understand. (I'm always slightly unhappy when I don't understand why a piece of code is working, although its nice that it does work!) Also I followed your link to the '...pass a variable from Activity to Fragment…' – Martin Clifford Nov 16 '15 at 18:56
  • which re-enforced your solution and I tend to agree with the commenters who say the developer.android.com documentation does not explain this area at all well ! – Martin Clifford Nov 16 '15 at 18:56
  • Glad it helped. I've had similar struggles with passing data between fragments, activities and view pagers... – QuantumTiger Nov 16 '15 at 21:34
  • In terms of the NPE it is all about making sure you don't access an element in the view until after it has been created, so reading the bundle in onCreateView is fine, but clearly from your experience the edit text field was still not created at that point – QuantumTiger Nov 16 '15 at 21:52