Null Pointer Exception In Fragments

16,240

Solution 1

your error is happening here:

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

and it's happening because the variable iv is still null.

you have to wait until after the Fragment is shown (inflated) in order to access the Views that were inflated into it.

for more, try reading about the Fragment lifecycle.

onCreateView()
The system calls this when it's time for the fragment to draw its user interface for the first time. To draw a UI for your fragment, you must return a View from this method that is the root of your fragment's layout. You can return null if the fragment does not provide a UI.

a very good way of creating this will be using the setArgs method and passing a Bundle with the 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;
    }
}

Solution 2

MyFragment3 newfragment = new MyFragment3();

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

You are trying to access imageview which will be created in onCreateView of the fragment. When you call newfragment.setImage(); your view is not yet created hence you are getting a NPE.

Share:
16,240
wolverine
Author by

wolverine

Updated on June 05, 2022

Comments

  • wolverine
    wolverine almost 2 years

    I am getting NullPointerException while Starting One Fragment From other Fragment. I am trying to call a method in the second Fragment after Starting 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 is:

    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 to overcome this problem.

  • wolverine
    wolverine almost 11 years
    I have to set the image From the First Fragment itself.. Is there any better way to do this?
  • wolverine
    wolverine almost 11 years
    when i call Fragment3() frag = new Fragment(), what happens? won't it create new fragment and the lifecycle methods like, oncreate, oncreateView?
  • thepoosh
    thepoosh almost 11 years
    go to the link attached, you can see exactly what method is called and when. you can't set images to null, and the View is not created until onCreateView is called
  • thepoosh
    thepoosh almost 11 years
    try using setArgs for passing this type of information to the fragment
  • wolverine
    wolverine almost 11 years
    what parameters can i pass in the args? like, i have 10 number of image views, Textviews.. So i think setArgs is not the alternative
  • wolverine
    wolverine almost 11 years
    Is there any better way to load the content in fragment3 dynamically from Frag 2?
  • Tarun
    Tarun almost 11 years
    Bundle args = new Bundle(); args.putInt("image", i); newfragment.setArguments(args); In MyFragment3 you can call getArguments().getInt("image", 0); to get the passed value to the fragment.
  • Michał Z.
    Michał Z. almost 11 years
    You can pass some booleans as arguments which will be indicating what you want to load. For example you can pass bundle with isSetImage boolean and then in onCreateView() depending on this flag you can set your image or not.
  • wolverine
    wolverine almost 11 years
    that is fine.. But i have more than 10 view that controlled by the main Activity. And i have some ArrayLists. I am new to Fragments, can u please help me with an example.
  • wolverine
    wolverine almost 11 years
    yeah.. Thank you.. It works perfect if i have less number of views. But in my case i have to use more than 10 views that are based on Previous Fragment
  • Michał Z.
    Michał Z. almost 11 years
    marakana.com/s/post/1250/android_fragments_tutorial read this article, it should help you understand fragments.
  • wolverine
    wolverine almost 11 years
    I read this Document.. In this he is doing only attaching the fragments, replacing.. In My case it is working.. But the problem is only when i try to call a method from Previous Fragment.
  • thepoosh
    thepoosh almost 11 years
    you cane create a helper class to take care of this. trust me, this is the correct way to go, it was designed like that, and all the Android sample projects are built like this.
  • wolverine
    wolverine almost 11 years
    Hmm.. I'll try this. Can you please mail me any example for doing this.. [email protected]