How to restore the scroll position of the text after rotating the screen?

In my Android layout, I have a TextView. This TextView displays a fairly large text that can be expanded, and it can scroll. Now that the phone is rotated, the view is destroyed and created, and I must set Text Text () TextView again, resetting the scroll position to the beginning.

I know that I can use getScrolly () and scrollTo () to go to the positions of the pixels, but due to a change in the width in the view, the lines become longer and the line that was in the pos 400 pixel can now be 250. Thus It is not very useful.

I need a way to find the first visible line in a TextView in onDestroy (), and then a way to make TextView scroll this text after rotation.

Any ideas?

+4
source share
2 answers

This is an old question, but I landed here when I was looking for a solution to the same problem, so this is what I came up with. I combined the ideas of the answers to these three questions:

I tried to extract only the appropriate code from my application, so please forgive any errors. Also note that if you turn the landscape and back, it may not end in the same position you started. For example, say, β€œPeter” is the first visible word in a portrait. When you turn into the landscape, Peter is the last word on his line, and the first is Larry. When you turn back, "Larry" will appear.

private static float scrollSpot; private ScrollView scrollView; private TextView textView; protected void onCreate(Bundle savedInstanceState) { textView = new TextView(this); textView.setText("Long text here..."); scrollView = new ScrollView(this); scrollView.addView(textView); // You may want to wrap this in an if statement that prevents it from // running at certain times, such as the first time you launch the // activity with a new intent. scrollView.post(new Runnable() { public void run() { setScrollSpot(scrollSpot); } }); // more stuff here, including adding scrollView to your main layout } protected void onDestroy() { scrollSpot = getScrollSpot(); } /** * @return an encoded float, where the integer portion is the offset of the * first character of the first fully visible line, and the decimal * portion is the percentage of a line that is visible above it. */ private float getScrollSpot() { int y = scrollView.getScrollY(); Layout layout = textView.getLayout(); int topPadding = -layout.getTopPadding(); if (y <= topPadding) { return (float) (topPadding - y) / textView.getLineHeight(); } int line = layout.getLineForVertical(y - 1) + 1; int offset = layout.getLineStart(line); int above = layout.getLineTop(line) - y; return offset + (float) above / textView.getLineHeight(); } private void setScrollSpot(float spot) { int offset = (int) spot; int above = (int) ((spot - offset) * textView.getLineHeight()); Layout layout = textView.getLayout(); int line = layout.getLineForOffset(offset); int y = (line == 0 ? -layout.getTopPadding() : layout.getLineTop(line)) - above; scrollView.scrollTo(0, y); } 
+11
source

TextView can save and restore its state for you. If you cannot use this, you can disable it and explicitly call methods:

http://developer.android.com/reference/android/widget/TextView.SavedState.html http://developer.android.com/reference/android/widget/TextView.html#onSaveInstanceState () http: // developer. android.com/reference/android/widget/TextView.html#onRestoreInstanceState(android.os.Parcelable )

+1
source

Source: https://habr.com/ru/post/1344651/


All Articles