如何在屏幕旋转后恢复textview滚动位置?
在我的Android布局中,我有一个TextView。这个TextView显示一个相当大的spannable文本,并且能够滚动。现在,当手机旋转时,视图被破坏并创建,并且我必须再次设置TextTe()TextView,将滚动位置重置为开头。如何在屏幕旋转后恢复textview滚动位置?
我知道我可以使用getScrolly()和scrollTo()滚动到像素位置,但由于视图宽度的变化,线条变得更长,这是在像素POS 400行现在可能是在250所以这不是很有帮助。
我需要一种方法来查找onDestroy()中的TextView中的第一个可见行,然后使TextView在旋转后滚动到该特定段落的文本。
任何想法?
TextView可以为您保存和恢复其状态。如果你不能够使用,你可以禁用,并明确调用的方法:
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)
这是一个古老的问题,但我在寻找相同问题的解决方案时登陆这里,所以这就是我想出的。我结合从答案的想法以下三个问题:
- Scroll TextView to text position
- Dynamically Modifying Contextual/Long-Press Menu in EditText Based on Position of Long Press
- ScrollView .scrollTo not working? Saving ScrollView position on rotation
我想从我的应用程序只提取相关的代码,所以请原谅任何错误。另请注意,如果您旋转到横向并返回,它可能不会以您开始的相同位置结束。例如,说“彼得”是肖像中第一个可见的单词。当你旋转到风景时,“彼得”是其最后一个词,第一个是“拉里”。当您旋转回来时,“拉里”将会显示。
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);
}
这工作得很好!应该被接受为答案。 – Matt 2013-06-08 00:49:42
同样的问题。 TextView只保存像素位置,而不是文本位置。旋转后,我必须计算一个新的像素位置,以便与之前一样显示相同的文本。 – Josh 2011-05-06 20:40:51