Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fragment id in android-support-v4 rev. 22

There are MainActivity (extends FragmentActivity) and MainActivityFragment (extends android.support.v4.app.Fragment). There are different layouts for portrait and landscape screen orientations for MainActivityFragment.

After switching version of android-support-v4 lib from 21.0.3 to 22.0.0 I get the following stacktrace while rotating the app:

java.lang.RuntimeException: Unable to start activity 
...
     Caused by: java.lang.ClassCastException: android.view.AbsSavedState$1 cannot be cast to android.widget.ScrollView$SavedState
            at android.widget.ScrollView.onRestoreInstanceState(ScrollView.java:1758)
            at android.view.View.dispatchRestoreInstanceState(View.java:13740)
            at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2887)
            at android.view.View.restoreHierarchyState(View.java:13718)
            at android.support.v4.app.Fragment.restoreViewState(Fragment.java:465)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:979)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1136)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1118)
            at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1927)
            at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:544)
            at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1236)
            at android.app.Activity.performStart(Activity.java:6006)
...

activity_main.xml:

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:id="@+id/fragment"
          android:name="com.example.myapplication.MainActivityFragment"
          tools:layout="@layout/fragment_main"
          android:layout_width="match_parent"
          android:layout_height="match_parent"/>

layout/fragment_main.xml:

<RelativeLayout 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:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                android:paddingBottom="@dimen/activity_vertical_margin"
                android:id="@+id/relativeLayout"
                tools:context=".MainActivityFragment">

    <TextView
        android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</RelativeLayout>

layout-land/fragment_main.xml:

<ScrollView 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:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                android:paddingBottom="@dimen/activity_vertical_margin"
                android:id="@+id/scrollView"
                tools:context=".MainActivityFragment">

    <TextView
        android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</ScrollView>

So both fragment layouts have different root ids. But seems it does not matter anymore in support-lib-v4 22.0.0. Moreover it's possible to find root view of both layouts only by passing R.id.fragment. Here is the code, and see explanations below:

public class MainActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onStart() {
        findViewById(R.id.relativeLayout); // (1) 
        findViewById(R.id.scrollView); // (2)
        findViewById(R.id.fragment); // (3)
    }
}

(1) - with rev. 21 returns RelativeLayout for portrait mode, null in landscape; with rev. 22 return null in both modes

(2) - with rev. 21 returns null for portrait mode, ScrollView in landscape; with rev. 22 return null in both modes

(3) - with rev. 21 returns layout with fragment inside for both modes; in rev. 22 returns RelativeLayout or ScrollView depending on orientation.

My questions: Is this change of API is documented somewhere? Should I change my layout/fragment code assuming that it is not a bug of support library?

like image 835
alex.dorokhov Avatar asked Dec 07 '25 07:12

alex.dorokhov


1 Answers

Activity and Fragment classes from Android system library (not support-lib-v4) on my Android 4.1 device have the same behavior like newest (22.1.1) version of support-lib-v4. So, I guess the "new" behavour is not a bug, but it is the fix.

like image 80
alex.dorokhov Avatar answered Dec 08 '25 21:12

alex.dorokhov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!