简体   繁体   中英

Application crashes when i try to save scroll position

My application has an activity which contains many textviews which are used to display a very long block of text so i have divided the text into many textviews. The problem occurs when i try to save the scroll position of the text for orientation changes and to retain the position when the application goes into the background. But when i change the orientation of the screen the application crashes.

Below is the code:

Chapter1.xml

<?xml version="1.0" encoding="utf-8"?>

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/scrollChapter1">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/Chapter1"
            android:textSize="17sp"
            android:padding="10px"
            android:id="@+id/txtChapter1Title"
            />
    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dip"
            android:width="0dip"
            android:textSize="16sp"
            android:padding="10px"
            android:text="@string/Chapter1ContentA"
            android:id="@+id/txtChapter1A"
            android:maxLength="9000"
            android:layout_below="@+id/txtChapter1Title"
            />
    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="0dip"
            android:width="0dip"
            android:textSize="16sp"
            android:padding="10px"
            android:text="@string/Chapter1ContentB"
            android:id="@+id/txtChapter1B"
            android:maxLength="9000"
            android:layout_below="@+id/txtChapter1A"
            />
    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="0dip"
            android:width="0dip"
            android:textSize="16sp"
            android:padding="10px"
            android:text="@string/Chapter1ContentC"
            android:id="@+id/txtChapter1C"
            android:maxLength="9000"
            android:layout_below="@+id/txtChapter1B"
            />
    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="0dip"
            android:width="0dip"
            android:textSize="16sp"
            android:padding="10px"
            android:text="@string/Chapter1ContentD"
            android:id="@+id/txtChapter1D"
            android:maxLength="9000"
            android:layout_below="@+id/txtChapter1C"
            />
    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="0dip"
            android:width="0dip"
            android:textSize="16sp"
            android:padding="10px"
            android:text="@string/Chapter1ContentE"
            android:id="@+id/txtChapter1E"
            android:maxLength="9000"
            android:layout_below="@+id/txtChapter1D"
            />
    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="0dip"
            android:width="0dip"
            android:textSize="16sp"
            android:padding="10px"
            android:text="@string/Chapter1ContentF"
            android:id="@+id/txtChapter1F"
            android:maxLength="9000"
            android:layout_below="@+id/txtChapter1E"
            />
    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="0dip"
            android:width="0dip"
            android:textSize="16sp"
            android:padding="10px"
            android:text="@string/Chapter1ContentG"
            android:id="@+id/txtChapter1G"
            android:maxLength="9000"
            android:layout_below="@+id/txtChapter1F"
            />
</RelativeLayout>
</ScrollView>

Chapter1.java:

public class chapter1 extends Activity {
@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.chapter1);
    WindowManager w = getWindowManager();
    Display d = w.getDefaultDisplay();
    if(d.getWidth() > d.getHeight()){
        Log.d("Orientation", "Landscape");
    }else{
        Log.d("Orientation", "Potrait");
    }
}
@Override
protected void onSaveInstanceState(Bundle outState){
    super.onSaveInstanceState(outState);
    final ScrollView scrollView = (ScrollView) findViewById(R.id.scrollChapter1);
    final TextView textView = (TextView) scrollView.getChildAt(0); //Crashes at this line
    final int firstVisibleLineOffset = textView.getLayout().getLineForVertical(scrollView.getScrollY());
    final int firstVisibleCharacterOffset = textView.getLayout().getLineStart(firstVisibleLineOffset);
    outState.putInt("ScrollViewContainerTextViewFirstVisibleCharacterOffset", firstVisibleCharacterOffset);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState){
    super.onRestoreInstanceState(savedInstanceState);
    final int firstVisibleCharacterOffset = savedInstanceState.getInt("ScrollViewContainerTextViewFirstVisibleCharacterOffset");
    final ScrollView scrollView = (ScrollView) findViewById(R.id.scrollChapter1);
    scrollView.post(new Runnable() {
        @Override
        public void run() {
            final TextView textView = (TextView) scrollView.getChildAt(0);
            final int firstVisibleLineOffset = textView.getLayout().getLineStart(firstVisibleCharacterOffset);
            final int pixelOffset = textView.getLayout().getLineTop(firstVisibleLineOffset);
            scrollView.scrollTo(0, pixelOffset);
        }
    });
}

}

LogCat:

07-18 15:52:39.921      806-806/com.example.ZindaRud D/Orientation﹕ Potrait
07-18 15:52:41.800      806-810/com.example.ZindaRud D/dalvikvm﹕ GC_CONCURRENT freed 155K, 4% free 7169K/7431K, paused 6ms+6ms
07-18 15:52:41.809      806-806/com.example.ZindaRud D/Orientation﹕ Potrait
07-18 15:52:44.500      806-806/com.example.ZindaRud W/TextLayoutCache﹕ computeValuesWithHarfbuzz -- need to force to single run
07-18 15:52:48.760      806-806/com.example.ZindaRud D/AndroidRuntime﹕ Shutting down VM
07-18 15:52:48.760      806-806/com.example.ZindaRud W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x409961f8)
07-18 15:52:48.809      806-806/com.example.ZindaRud E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.ClassCastException: android.widget.RelativeLayout cannot be cast to android.widget.TextView
        at com.example.ZindaRud.chapter1.onSaveInstanceState(chapter1.java:31)
        at android.app.Activity.performSaveInstanceState(Activity.java:1113)
        at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1185)
        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3321)
        at android.app.ActivityThread.access$700(ActivityThread.java:122)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1150)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4340)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
        at dalvik.system.NativeStart.main(Native Method)

Thanks guys fixed the ClassCastException, but now it does not seem save and retain the scroll position when the orientation changes.

You are getting cast exception and its obvious because you are casting RelativeLayout to a TextView at line

final TextView textView = (TextView) scrollView.getChildAt(0);

ScrollView's immediate child at 0 is RelativeLayout as seen in the Layout.

you have to use it like this sorry for the mistake. Reusing what @micro.pavo sayed

final RelativeLayout rLayout = (RelativeLayout) scrollView.getChildAt(0);
final TextView textView = (TextView) rLayout.getChildAt(0);

or you can access directly

final TextView textView = (TextView)findViewById(R.id.txtChapter1Title);

final TextView textView = (TextView) scrollView.getChildAt(0); //Crashes at this line

RelativeLayout is the child of ScrollView and you are casting it to TextView .

So,

java.lang.ClassCastException: android.widget.RelativeLayout cannot be cast to android.widget.TextView

You are getting a ClassCastException because you are trying to cast a RelativeLayout into TextView on this line

final TextView textView = (TextView) scrollView.getChildAt(0);

As seen in the xml code, the first child under ScrollView is RelativeLayout , try making it something like this:

final RelativeLayout rLayout = (RelativeLayout) scrollView.getChildAt(0);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM