I'm trying to use a FrameLayout on one of my activities. I want this FrameLayout to be a placeholder in an activity and I want to add/replace/remove fragments inside it.
I have a simple cafe app used for studying android. For simplicity I will post the code for the Cake and Breads category.
Problem: NullPointerException. I don't know the reason WHY my fragment's view is null. I'm guessing maybe the fragment lifecycle didn't run so the view was not inflated thus accessing the view throws a nullpointer? Please help me understand WHY a nullpointer is thrown.
Flow of the App
User selects a specific cake or bread in a ListFragment > CakeAndBreadActivity is called > Display Cake or Bread specific detail
I'm looking for: the explanation and reason behind the NullPointerException in the view and How can I display the Cakes and Bread details into the fragment when using FrameLayout.
NullPointerException
--------- beginning of crash
10-25 01:41:21.550 2374-2374/com.cafe E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.cafe, PID: 2374
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.cafe/com.cafe.CakeAndBreadActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
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)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
at com.cafe.CakeAndBreadDetailFragment.displayCakeAndBreadDetails(CakeAndBreadDetailFragment.java:97)
at com.cafe.CakeAndBreadActivity.displayCakeAndBreadDetails(CakeAndBreadActivity.java:30)
at com.cafe.CakeAndBreadActivity.onCreate(CakeAndBreadActivity.java:19)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
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)
CakeAndBreadActivity
public class CakeAndBreadActivity extends Activity implements CakeAndBreadDetailFragment.onCakeAndBreadDetailFragmentListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cake_and_bread);
displayCakeAndBreadDetails();
}
public void displayCakeAndBreadDetails(){
Intent cakeAndBreadIntent = getIntent();
int cakeAndBreadId = Integer.valueOf(cakeAndBreadIntent.getIntExtra("cakeAndBreadNumber", 0));
CakeAndBreadDetailFragment cakeAndBreadDetail = new CakeAndBreadDetailFragment();
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
cakeAndBreadDetail.displayCakeAndBreadDetails(cakeAndBreadId);
fragmentTransaction.replace(R.id.cake_and_bread_detail_frame_layout_id, cakeAndBreadDetail);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
@Override
public void onCakeAndBreadDetail(int id) {
}
}
activity_cake_and_bread.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.cafe.CakeAndBreadActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/cake_and_bread_detail_frame_layout_id"/>
</LinearLayout>
CakeAndBreadDetailFragment
public class CakeAndBreadDetailFragment extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private String mParam1;
private String mParam2;
private onCakeAndBreadDetailFragmentListener mListener;
public CakeAndBreadDetailFragment() {
}
public static CakeAndBreadDetailFragment newInstance(String param1, String param2) {
CakeAndBreadDetailFragment fragment = new CakeAndBreadDetailFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_cake_and_bread_detail, container, false);
}
public void onButtonPressed(int id) {
if (mListener != null) {
mListener.onCakeAndBreadDetail(id);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof onCakeAndBreadDetailFragmentListener) {
mListener = (onCakeAndBreadDetailFragmentListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement onCakeAndBreadDetailFragmentListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface onCakeAndBreadDetailFragmentListener {
// TODO: Update argument type and name
void onCakeAndBreadDetail(int id);
}
public void displayCakeAndBreadDetails(int id){
CakeAndBread cakeAndBread = (CakeAndBread)CakeAndBread.getCakeAndBreadList().get(id);
View cakeAndBreadView = getView();
TextView cakeAndBreadTextView = (TextView)cakeAndBreadView.findViewById(R.id.cake_and_bread_detail_fragment_id);
cakeAndBreadTextView.setText(cakeAndBread.getCakeAndBreadName() + " " + cakeAndBread.getCakeAndBreadNutritionFacts());
}
}
fragment_cake_and_bread_detail.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.cafe.CakeAndBreadDetailFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:id="@+id/cake_and_bread_detail_fragment_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
EDIT: as suggested, the fragment was not completely loaded when I'm trying to access the view, thus the nullpointerexception is thrown. Now my problem is the framelayout or the fragment doesn't show the textview that I placed in the fragment, how do I solve this? I'm passing cake and bread id and then setting the text in the setText(...) method of the TextView.