Pregunta

I have two Fragments (MainFragment and AnotherFragment) and MainActivity as described below.

In "onCreate" of MainActivity, I am adding MainFragment. Upon clicking I am adding AnotherFragment which takes data in two editText fields and pass them to mainfragment which display in textView fields.

MainFragment.java

Button a;
TextView t1,t2;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_main, container, false);
    return rootView;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    a = (Button) getActivity().findViewById(R.id.button);
    t1 = (TextView) getActivity().findViewById(R.id.textView);
    t2 = (TextView) getActivity().findViewById(R.id.textView2);
    //a.setOnClickListener(this);
}

public void showData(String a, String b) {
    t1.setText(a);
    t2.setText(b);
}

AnotherFragment.java

Button b;
EditText e1,e2;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_another, container, false);
    return rootView;
}

Comm comm;
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    comm = (Comm) activity;
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    b = (Button) getActivity().findViewById(R.id.buttonA);
    e1 = (EditText) getActivity().findViewById(R.id.editText);
    e2 = (EditText) getActivity().findViewById(R.id.editText2);
    b.setOnClickListener(this);
}

@Override
public void onClick(View view) {
    comm.sendData(e1.getText().toString(), e2.getText().toString());
}

public interface Comm {
    public void sendData(String a, String b);
}

MainActivity.java

FragmentManager fragmentManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    fragmentManager = getSupportFragmentManager();
    if (savedInstanceState == null) {
        fragmentManager.beginTransaction()
                .add(R.id.container, new MainFragment())
                .commit();
    }
}

@Override
public void sendData(String a, String b) {
    MainFragment mainFragment = new MainFragment();
    getSupportFragmentManager().beginTransaction().replace(R.id.container,mainFragment).commit();
    mainFragment.showData(a,b);
}

public void newone(View view) {
    AnotherFragment anotherFragment = new AnotherFragment();
    getSupportFragmentManager().beginTransaction().replace(R.id.container,anotherFragment).commit();
}

The fragment replace is causing nullpointerexception.

java.lang.NullPointerException
        at com.exa.researchanddev.app.MainFragment.showData(MainFragment.java:31)
        at com.exa.researchanddev.app.MainActivity.sendData(MainActivity.java:57)
        at com.exa.researchanddev.app.AnotherFragment.onClick(AnotherFragment.java:42)
        at android.view.View.performClick(View.java:4084)
        at android.view.View$PerformClick.run(View.java:16966)
        at android.os.Handler.handleCallback(Handler.java:615)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4745)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)

And also,...

@Override
public void sendData(String a, String b) {
    Toast.makeText(this, a + " = "+ b, Toast.LENGTH_SHORT).show();
    MainFragment mainFragment = new MainFragment();
    getSupportFragmentManager().beginTransaction().replace(R.id.container,mainFragment).commit();
    //mainFragment.showData(a,b);
}

when I commented the showData function the code is working fine. the fragments are getting replaced.

When not commented, NullPointerException is thrown.

¿Fue útil?

Solución

Your problem is here:

@Override
public void sendData(String a, String b) {
    MainFragment mainFragment = new MainFragment();
    getSupportFragmentManager().beginTransaction().replace(R.id.container,mainFragment).commit();
    mainFragment.showData(a,b); 
}

The transaction of a Fragment is asynchronous. Because of this the TextViews in your Fragment are null. A better way would be to pass the Strings as arguments to the Fragment.

@Override
public void sendData(String a, String b) {
    MainFragment mainFragment = new MainFragment();
    Bundle bundle = new Bundle();
    bundle.putString("A", a);
    bundle.putString("B", b);
    mainFragment.setArguments(bundle);
    getSupportFragmentManager().beginTransaction().replace(R.id.container,mainFragment).commit();

}

Now you can read the data of the arguments in your Fragments onCreateView.

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    a = (Button) getActivity().findViewById(R.id.button);
    t1 = (TextView) getActivity().findViewById(R.id.textView);
    t2 = (TextView) getActivity().findViewById(R.id.textView2);

    if (getArguments() != null) {
          t1.setText(getArguments().getString("A"));
          t2.setText(getArguments().getString("B"));
    }
}

Otros consejos

Your problem here is that this:

a = (Button) getActivity().findViewById(R.id.button);
...

Is called before this

return inflater.inflate(R.layout.fragment_another, container, false);

The NPE that you are getting is because of the fact that you are trying to reference the ID of a view [R.id.button] from a layout that has yet to be inflated.

Try moving a = ... and the following variable assignments to after the view has been inflated.

Override the onLayout method, which will be called after the view has been inflated. In this, you should be able to do your variable assignments from layout.

protected void onLayout(boolean changed, int l, int t, int r, int b){
    super.onLayout(changed, l, t, r, b);
    ...
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top