Search code examples
androidandroid-fragmentsandroid-listfragmentillegalstateexception

illegalstateexception did not create a view when screen orientation changes


I have been trying to make an app that opens a listview fragment (GradeListFragment) from an activity (GradeListActivity). When I click an item, it opens a new fragment (GradeDetailFragment). If in portrait mode, it replaces the list fragment in fragment1. If in landscape, it replaces the empty fragment2. My problem is that the app crashes when I switch orientation. Switching from both perspectives gets the same error.

04-09 12:10:52.240: E/AndroidRuntime(2221): FATAL EXCEPTION: main
04-09 12:10:52.240: E/AndroidRuntime(2221): Process:     bcs421.christophergoepfert.hwk.gradeapp.presentation, PID: 2221
04-09 12:10:52.240: E/AndroidRuntime(2221): java.lang.RuntimeException:   Unable to start activity    ComponentInfo{bcs421.christophergoepfert.hwk.gradeapp.presentation/bcs421.christ     ophergoepfert.hwk.gradeapp.presentation.GradeListActivity}:   android.view.InflateException: Binary XML file line #8: Error inflating class   fragment
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3912)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.app.ActivityThread.access$900(ActivityThread.java:144)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at    android.os.Handler.dispatchMessage(Handler.java:102)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.os.Looper.loop(Looper.java:135)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.app.ActivityThread.main(ActivityThread.java:5221)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at java.lang.reflect.Method.invoke(Native Method)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at java.lang.reflect.Method.invoke(Method.java:372)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at     com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
04-09 12:10:52.240: E/AndroidRuntime(2221): Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:763)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:377)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.app.Activity.setContentView(Activity.java:2144)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at bcs421.christophergoepfert.hwk.gradeapp.presentation.GradeListActivity.onCreate(GradeListActivity.java:29)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.app.Activity.performCreate(Activity.java:5933)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
04-09 12:10:52.240: E/AndroidRuntime(2221):     ... 11 more
04-09 12:10:52.240: E/AndroidRuntime(2221): Caused by: java.lang.IllegalStateException: Fragment android.app.ListFragment did not create a view.
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2145)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.app.Activity.onCreateView(Activity.java:5282)
04-09 12:10:52.240: E/AndroidRuntime(2221):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733)

MainActivity does not crash when it restarts.

public class MainActivity extends Activity{

public GradeCollection collection;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

        //grade data 
    }

}
public void startGradeListActivity(View v){

    Intent i = new Intent(MainActivity.this, GradeListActivity.class);
    //putextra gradecollection
    startActivity(i);

    }
}

The main_activity xml

<TextView
    android:id="@+id/textViewName"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/name" />

<RatingBar
    android:id="@+id/ratingBar1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:numStars="4"
    android:stepSize="1" />

<TextView
    android:id="@+id/textViewGradeNumber"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/gradeNumber" />

<TextView
    android:id="@+id/textViewGradeLetter"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="TextView" />

<Button
    android:id="@+id/buttonViewGrades"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:onClick="startGradeListActivity"
    android:text="@string/viewGrades" />

GradeListActivity crashes at ft.commit();, maybe the problem is that I'm importing android.support.v4.app.FragmentActivity;?

public class GradeListActivity extends FragmentActivity {
//private GradeCollection listGrades;
//private ArrayList<String> listCatagory;
//private ArrayAdapter<String> listAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.catagory_list);

    ListFragment fragment = new GradeListFragment();
    FragmentManager fm = getFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    ft.replace(R.id.fragment1, fragment);

    ft.commit();

    }
}

This is GradeListFragment.

public class GradeListFragment extends ListFragment{

 @Override
 public View onCreateView(  LayoutInflater inflater,
            ViewGroup container,
            Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        View v = inflater.inflate(R.layout.fragment_category, container, false);
       //data handling
        return v;
     }
 }

Here is the xml for catagory_list portrait

<fragment
    android:id="@+id/fragment1"
    android:name="android.app.ListFragment"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1.03" />

And here is the landscape

<fragment
    android:id="@+id/fragment1"
    android:name="android.app.ListFragment"
    android:layout_width="271dp"
    android:layout_height="match_parent" />

<FrameLayout
    android:id="@+id/fragment2"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

I have omitted the actual data being passed as well as GradeDetailFragment because I know those aren't the problem. I have seen this page but I do not really understand how it works so I can't test it. I have tried onConfigChange in the manifest but then I can't change to the appropriate layout. If anyone could solve this issue or explain the link, I would be very grateful.


Solution

  • Look this doc:

    Note: When you add a fragment to an activity layout by defining the fragment in the layout XML file, you cannot remove the fragment at runtime. If you plan to swap your fragments in and out during user interaction, you must add the fragment to the activity when the activity first starts.

    So you can not replace the R.id.fragment1 at runtime like:

    ft.replace(R.id.fragment1, fragment); //wrong
    

    then the correct way to implement fragment changing at runtime, you can use fragment container FrameLayout to replace Fragment for your R.id.fragment1 as:

    <FrameLayout
       android:id="@+id/fragment1"       
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_weight="1.03" />
    

    then you can add/replace fragment in R.id.fragment1.

    Hope this help!