1

Having problems getting Fragment to Activity communication working properly..

I have an edit box in a Fragment and I need it to send its value back to the main activity after each edit.

Fragment Class:

public class FragA extends Fragment {

    FragAInt mCallback;

    public interface FragAInt{
        public void onEditBoxEdited(String boxContent);
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
       View view =  inflater.inflate(R.layout.fragment_a, container, false);
       final View et = view.findViewById(R.id.eboxa) ;

        ((EditText) et).addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

                // TODO Auto-generated method stub

            }
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                // TODO Auto-generated method stub
            }

            @Override
            public void afterTextChanged(Editable s) {
                mCallback.onEditBoxEdited(((EditText) et).getText().toString());
            }
        });
        return view;
    }
}

MainActivity

public class MainActivity extends FragmentActivity implements FragA.FragAInt{

    private String editBoxVal;

    public void onEditBoxEdited(String editBoxContent){
        this.editBoxVal= editBoxContent;
    }
}

The app will run but it will crash as soon as you type in the exit box with a null pointer exception.

Where have I gone wrong?

Full error:

java.lang.NullPointerException: 
Attempt to invoke interface method 'void nemo.myapplication.FragA$FragAInt.onEditBoxEdited(java.lang.String)' on a null object reference
at nemo.myapplication.FragA$1.afterTextChanged(FragA.java:49)
at android.widget.TextView.sendAfterTextChanged(TextView.java:8017)
at android.widget.TextView$ChangeWatcher.afterTextChanged(TextView.java:10182)
at android.text.SpannableStringBuilder.sendAfterTextChanged(SpannableStringBuilder.java:1043)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:560)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:492)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:34)
at android.view.inputmethod.BaseInputConnection.replaceText(BaseInputConnection.java:685)
at android.view.inputmethod.BaseInputConnection.setComposingText(BaseInputConnection.java:445)
at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:340)
at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:78)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:234)
at android.app.ActivityThread.main(ActivityThread.java:5526)
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)
Adrian M
  • 325
  • 2
  • 12
  • Add error which you have. I guess that getting reference to EditText view is null. and you are trying to invoke methods on it. mCallback is not initialized, check this one. – Rafal Nov 24 '16 at 02:28
  • Is that all your code? where are you assigning the mCallback variable? How are you adding the fragment to the activity? – diedu Nov 24 '16 at 02:32
  • That is all my code. Im going off this example: https://developer.android.com/training/basics/fragments/communicating.html I did have that onAttach function but it complained that the function is deprecated. – Adrian M Nov 24 '16 at 02:35

1 Answers1

1

You need to assign the mCallback variable. I think you missed that part, you can use onAttach event.

public class FragA extends Fragment {

    FragAInt mCallback;

    public interface FragAInt{
        public void onEditBoxEdited(String boxContent);
    }

    public FragA(FragAInt mCallback) {
        this.mCallback = mCallback;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (FragAInt) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnHeadlineSelectedListener");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
       View view =  inflater.inflate(R.layout.fragment_a, container, false);
       final View et = view.findViewById(R.id.eboxa) ;

        ((EditText) et).addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

                // TODO Auto-generated method stub

            }
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                // TODO Auto-generated method stub
            }

            @Override
            public void afterTextChanged(Editable s) {
                mCallback.onEditBoxEdited(((EditText) et).getText().toString());
            }
        });
        return view;
    }
}
diedu
  • 19,277
  • 4
  • 32
  • 49
  • Ah. Android Studio complains that the function onAttach is deprecated so I assumed that meant I shouldnt use it, or at least it wasnt needed anymore. Thanks – Adrian M Nov 24 '16 at 02:47
  • that's interesting. I found this http://stackoverflow.com/questions/32083053/android-fragment-onattach-deprecated, It would be good to implement any of the answer to make sure your app works in all the sdk versions your are targeting – diedu Nov 24 '16 at 02:58