我想要的是,当设备改变方向时,纵向时屏幕上的顶线仍然是横向屏幕上的顶线。反之亦然。
由于纵向和横向的屏幕宽度可能不同,文本的线宽,也就是TextView
和的宽度ScrollView
,会有所不同。因此,换行在不同的屏幕配置(纵向与横向,大与小)中会有所不同。在不同的情况下,换行符将位于不同的位置。
有三个不太完美的解决方案供您参考。也说明了它们的缺点。
首先,最基本的方法:
(1) 仅以像素为单位存储 y 偏移量
为什么这不是那么完美:
在纵向中,线条被换行。
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
想象一下在保存时以纵向阅读Line_2_Word_A
(在屏幕顶部)。当更改为横向时,它将显示Line_3_Word_A
(在屏幕顶部)。(因为从顶部开始有两行像素偏移。)
然后我想出了一个方法,
(2) 通过保存滚动百分比
@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
想象一下在保存时以纵向阅读Line_2_Word_A
(在屏幕顶部)。当更改为横向时,它将显示Line_3_Word_A
(在屏幕顶部)。(因为它滚动了 50%。)
然后我发现这种方法确实
(3) 存储第一条可见行
请看一下(第一个答案):如何在屏幕旋转后恢复textview滚动位置?
为什么这不是那么完美:
在纵向中,线条被换行。
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
想象一下在保存时以纵向阅读Line_1_Word_E
(在屏幕顶部)。当更改为横向时,它将显示Line_3_Word_A
(在屏幕顶部)。(因为它是第三行。)
一个完美的方案是,在横向中,在屏幕顶部显示Line_1_Word_A
(以及)。Line_1_Word_E
您能否提出一个完美的方法?
编辑:
想了想,方法(3)其实和方法(1)是一样的吗?:-/
编辑2:
好吧,我刚刚提出了另一种比上述三种方法不那么完美但更完美的方法:
(4) 基于段落的存储
将段落(或文本块)分成不同的 TextView 对象。
然后通过方法(3)之类的代码,或者任何其他方式,不难检测出哪个段落(或块),即哪个TextView对象,当前在屏幕的顶部。
然后恢复并向下滚动到该段落(或块)。答对了!
正如我所说,它不是那么完美。但至少用户可以回到他/她正在阅读的那个段落(或块)。他/她只需往下看一点就能找到那条特定的线。(或者用前几行来提醒读者可能会更好,即从段落的开头阅读。)我知道如果我们有一个很长很长的段落可能会非常糟糕:-/
好吧,我们实际上可以“改进”这种方法。把它降到单词级别,一个单词一个TextView。所以它在逻辑上是“完美的”。但是,我想,这不是一个明智的选择。
PS浴室永远是头脑风暴的最佳场所(-: