Null pointer exception in fragments

I get a NullPointerException when starting one fragment from another fragment. I am trying to call a method in the second fragment after running the fragment dynamically.

Here is my logcat:

05-20 09:58:31.907: E/AndroidRuntime(2585): FATAL EXCEPTION: main 05-20 09:58:31.907: E/AndroidRuntime(2585): java.lang.NullPointerException 05-20 09:58:31.907: E/AndroidRuntime(2585): at com.exercise.FragmentTest.MyFragment3.setImage(MyFragment3.java:22) 05-20 09:58:31.907: E/AndroidRuntime(2585): at com.exercise.FragmentTest.FragmentTestActivity$1.onClick(FragmentTestActivity.java:48) 05-20 09:58:31.907: E/AndroidRuntime(2585): at android.view.View.performClick(View.java:4204) 05-20 09:58:31.907: E/AndroidRuntime(2585): at android.view.View$PerformClick.run(View.java:17355) 05-20 09:58:31.907: E/AndroidRuntime(2585): at android.os.Handler.handleCallback(Handler.java:725) 05-20 09:58:31.907: E/AndroidRuntime(2585): at android.os.Handler.dispatchMessage(Handler.java:92) 05-20 09:58:31.907: E/AndroidRuntime(2585): at android.os.Looper.loop(Looper.java:137) 05-20 09:58:31.907: E/AndroidRuntime(2585): at android.app.ActivityThread.main(ActivityThread.java:5041) 05-20 09:58:31.907: E/AndroidRuntime(2585): at java.lang.reflect.Method.invokeNative(Native Method) 05-20 09:58:31.907: E/AndroidRuntime(2585): at java.lang.reflect.Method.invoke(Method.java:511) 05-20 09:58:31.907: E/AndroidRuntime(2585): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 05-20 09:58:31.907: E/AndroidRuntime(2585): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 05-20 09:58:31.907: E/AndroidRuntime(2585): at dalvik.system.NativeStart.main(Native Method) 

And my main activity code:

 public class FragmentTestActivity extends FragmentActivity{ Fragment fragment; Button btnFragment1, btnFragment2, btnFragment3; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btnFragment1 = (Button)findViewById(R.id.displayfragment1); btnFragment2 = (Button)findViewById(R.id.displayfragment2); btnFragment3 = (Button)findViewById(R.id.displayfragment3); // get an instance of FragmentTransaction from your Activity FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); //add a fragment MyFragment myFragment = new MyFragment(); fragmentTransaction.add(R.id.myfragment, myFragment); fragmentTransaction.commit(); btnFragment1.setOnClickListener(btnFragmentOnClickListener); btnFragment2.setOnClickListener(btnFragmentOnClickListener); btnFragment3.setOnClickListener(btnFragmentOnClickListener); } Button.OnClickListener btnFragmentOnClickListener = new Button.OnClickListener(){ @Override public void onClick(View v) { if(v == btnFragment3){ MyFragment3 newfragment = new MyFragment3(); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); // Replace whatever is in the fragment_container view with this fragment, // and add the transaction to the back stack transaction.replace(R.id.myfragment, newfragment); transaction.addToBackStack(null); // Commit the transaction transaction.commit(); newfragment.setImage(); return; } // TODO Auto-generated method stub Fragment newFragment = null; // Create new fragment if(v == btnFragment1){ newFragment = new MyFragment(); } else if(v == btnFragment2){ newFragment = new MyFragment2(); } FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); // Replace whatever is in the fragment_container view with this fragment, // and add the transaction to the back stack transaction.replace(R.id.myfragment, newFragment); transaction.addToBackStack(null); // Commit the transaction transaction.commit(); // Create new transaction }}; } 

And my Fragment3 class:

 public class MyFragment3 extends Fragment { ImageView iv; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub View myFragmentView = inflater.inflate(R.layout.fragmentlayout3, container, false); iv = (ImageView)myFragmentView.findViewById(R.id.image); return myFragmentView; } public void setImage(){ iv.setImageResource(R.drawable.penguins); } } 

Please help me overcome this problem.

+4
source share
4 answers

your error happens here:

 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); newfragment.setImage(); 

and this is because the iv variable is still null .

you need to wait until the fragment is shown (inflated) in order to access the views that were inflated in it.

try reading about the fragment life cycle .

onCreateView ()
The system calls this when the time for the fragment first displays its user interface. To draw a user interface for your fragment, you must return the view from this method, which is the root of the fragment layout. You can return null if the fragment does not provide a user interface.

A very good way to create this would be to use the setArgs method and pass a Bundle with information about your image.

try using this code:

 public MyFragment3 extends Fragment { public static final IMAGE_RES = "IMAGE_RES"; private int imageRes; private ImageView iv; public static MyFragment3 init(int imageRes) { MyFragment3 frag = new MyFragment3(); Bundle args = new Bundle(); args.putInt(IMAGE_RES, imageRes); frag.setArguments(args); return frag; } public void onCreate(Bundle savedInstanceState) { super.onCreate(SavedInstanceState); imageRes = (getArguments() != null)? getArguments().getInt(IMAGE_RES) : 0; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View myFragmentView = inflater.inflate(R.layout.fragmentlayout3, container, false); iv = (ImageView)myFragmentView.findViewById(R.id.image); iv.setImageResource(imageRes); return myFragmentView; } } 
+3
source
 MyFragment3 newfragment = new MyFragment3(); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); newfragment.setImage(); 

You are trying to access the image view that will be created in the onCreateView fragment. When you call newfragment.setImage(); , your view has not been created yet, you get NPE.

+4
source

You cannot do it this way because onCreateView has not been called yet, so your iv is null. You can put iv.setImageResource(R.drawable.penguins); in onCreateView() or maybe onAttach() (I'm not sure about the second).

0
source

Use getActivity.findViewById in fragment

 public class MyFragment3 extends Fragment { ImageView iv; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub View myFragmentView = inflater.inflate(R.layout.fragmentlayout3, container, false); iv = (ImageView)getActivity.findViewById(R.id.image); return myFragmentView; } public void setImage(){ iv.setImageResource(R.drawable.penguins); } } 
0
source

Source: https://habr.com/ru/post/1481737/


All Articles