これは古い質問ですが、同じ問題の解決策を探すときにここにたどり着いたので、これが私が思いついたものです。私はこれらの3つの質問に対する答えからのアイデアを組み合わせました:
アプリから関連するコードのみを抽出しようとしましたので、エラーはご容赦ください。また、横向きに回転して戻ると、開始した位置と同じ位置で終了しない場合があることに注意してください。たとえば、「Peter」がポートレートで最初に表示される単語であるとします。横向きに回転すると、「Peter」がその行の最後の単語で、最初の単語が「Larry」です。後ろに回転すると、「ラリー」が表示されます。
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);
}