我想要的是,在设备更改方向时,屏幕中的顶行在纵向时仍然是横向屏幕的顶行。反之亦然。
由于纵向和横向之间的屏幕宽度可能不同,因此文本的线宽(也就是TextView
和ScrollView
的宽度)会有所不同。因此,在不同的屏幕配置(纵向与横向,大与小)中,换行将有所不同。在不同的情况下,换行符将处于不同的位置。
有三种 不那么完美的 解决方案供您参考。还解释了它们的缺点。
首先,最基本的方法:
为什么这不是那么完美:
在肖像中,线条被包裹。
Line_1_Word_A Line_1_Word_B Line_1_Word_C
Line_1_Word_D
Line_2_Word_A Line_2_Word_B Line_2_Word_C
Line_2_Word_D
Line_3_Word_A Line_3_Word_B Line_3_Word_C
Line_3_Word_D
在横向中,行不包裹。
Line_1_Word_A Line_1_Word_B Line_1_Word_C Line_1_Word_D
Line_2_Word_A Line_2_Word_B Line_2_Word_C Line_2_Word_D
Line_3_Word_A Line_3_Word_B Line_3_Word_C Line_3_Word_D
想象一下,在保存时,在Portrait中阅读Line_2_Word_A
(在屏幕顶部)。当更改为横向时,它将显示Line_3_Word_A
(在屏幕顶部)。 (因为顶部有两行偏移的像素。)
然后我提出了一种方法,
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
final ScrollView scrollView = (ScrollView) findViewById(R.id.Trial_C_ScrollViewContainer);
outState.putFloatArray(ScrollViewContainerScrollPercentage,
new float[]{
(float) scrollView.getScrollX()/scrollView.getChildAt(0).getWidth(),
(float) scrollView.getScrollY()/scrollView.getChildAt(0).getHeight() });
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
final float[] scrollPercentage = savedInstanceState.getFloatArray(ScrollViewContainerScrollPercentage);
final ScrollView scrollView = (ScrollView) findViewById(R.id.Trial_C_ScrollViewContainer);
scrollView.post(new Runnable() {
public void run() {
scrollView.scrollTo(
Math.round(scrollPercentage[0]*scrollView.getChildAt(0).getWidth()),
Math.round(scrollPercentage[1]*scrollView.getChildAt(0).getHeight()));
}
});
}
当且仅当每行的长度相同时,这才能完美地工作。
为什么这不是那么完美:
在肖像中,线条被包裹。
Line_1_Word_A Line_1_Word_B
Line_1_Word_C Line_1_Word_D
Line_1_Word_E Line_1_Word_F
Line_2_Word_A
Line_3_Word_A
Line_4_Word_A
在横向中,行不包裹。
Line_1_Word_A Line_1_Word_B Line_1_Word_C Line_1_Word_D Line_1_Word_E Line_1_Word_F
Line_2_Word_A
Line_3_Word_A
Line_4_Word_A
想象一下,在保存时,在Portrait中阅读Line_2_Word_A
(在屏幕顶部)。当更改为横向时,它将显示Line_3_Word_A
(在屏幕顶部)。 (因为它滚动了50%。)
然后我发现这种方法确实
请看一下(第一个答案):How to restore textview scrolling position after screen rotation?
为什么这不是那么完美:
在肖像中,线条被包裹。
Line_1_Word_A Line_1_Word_B
Line_1_Word_C Line_1_Word_D
Line_1_Word_E Line_1_Word_F
Line_2_Word_A
Line_3_Word_A
Line_4_Word_A
在横向中,行不包裹。
Line_1_Word_A Line_1_Word_B Line_1_Word_C Line_1_Word_D Line_1_Word_E Line_1_Word_F
Line_2_Word_A
Line_3_Word_A
Line_4_Word_A
想象一下,在保存时,在Portrait中阅读Line_1_Word_E
(在屏幕顶部)。当更改为横向时,它将显示Line_3_Word_A
(在屏幕顶部)。 (因为它是第三行。)
完美的一个是,在横向广告中,在屏幕顶部显示Line_1_Word_A
(以及Line_1_Word_E
)。
请你建议一个完美的方法吗?
经过一番思考,方法(3)实际上与方法(1)相同吗? : - /
好吧,我刚刚提出了另一种 不那么完美但更完美的 方法,而不是上述三种方法:
将段落(或文本块)分隔为不同的TextView对象。
然后通过类似方法(3)的代码或任何其他方式,不难发现哪个段落(或块),即哪个TextView对象当前位于屏幕顶部。
然后恢复并向下滚动到该段落(或块)。宾果!
正如我所说, 不那么完美 。但至少用户可以回到他/她正在阅读的段落(或块)。他/她只需要向下看一下就可以找到那条特定的线。 (或者甚至可能更好地提醒读者前几行,即从段落的开头读取。)我知道如果我们有一个很长的长段落可能会非常糟糕: - /
好吧,我们实际上可以“改进”这种方法。简化为单词级别,单词为TextView。所以它在逻辑上是“完美的”。但是,我想,这不是一个明智的选择。
P.S。浴室一直是头脑风暴的最佳场所( - :
答案 0 :(得分:14)
Sh ....(对不起,我太兴奋了。如果你发现任何错误/错误/弱点,请给我你宝贵的建议,请随时纠正我。: - )
切掉垃圾。你去吧!!!
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
final ScrollView scrollView = (ScrollView) findViewById(R.id.Trial_C_ScrollViewContainer);
final TextView textView = (TextView) scrollView.getChildAt(0);
final int firstVisableLineOffset = textView.getLayout().getLineForVertical(scrollView.getScrollY());
final int firstVisableCharacterOffset = textView.getLayout().getLineStart(firstVisableLineOffset);
outState.putInt(ScrollViewContainerTextViewFirstVisibleCharacterOffset, firstVisableCharacterOffset);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
final int firstVisableCharacterOffset = savedInstanceState.getInt(ScrollViewContainerTextViewFirstVisibleCharacterOffset);
final ScrollView scrollView = (ScrollView) findViewById(R.id.Trial_C_ScrollViewContainer);
scrollView.post(new Runnable() {
public void run() {
final TextView textView = (TextView) scrollView.getChildAt(0);
final int firstVisableLineOffset = textView.getLayout().getLineForOffset(firstVisableCharacterOffset);
final int pixelOffset = textView.getLayout().getLineTop(firstVisableLineOffset);
scrollView.scrollTo(0, pixelOffset);
}
});
}
就是这样。 : - )
如果对您有所帮助,请拍手。 < - 这很重要!!
如果您愿意,请点击那个小直立三角形。 (确保你先拍了拍手!)
欢呼声,
midnite