Reputation: 1665
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.
Upvotes: 5
Views: 17656
Reputation: 16017
In my case the problem was because I was trying to use the SwipeRefreshLayout
as the root element of the fragment's layout XML. Once I added the SwipeRefreshLayout
as a child of the ConstraintLayout
used by the fragment it started working.
Upvotes: 0
Reputation: 52
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);
}
}
Upvotes: 0
Reputation: 12587
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;
}
}
Upvotes: 4
Reputation: 4119
You can't 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 the onCreateView()
or maybe in onAttach()
(I'm not sure about the second one).
Upvotes: 0
Reputation: 13808
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.
Upvotes: 4