Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/224.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 最好的方法:节省和;恢复ScrollView中的TextView位置_Android_Android Layout_Textview_Android Orientation_Android Scrollview - Fatal编程技术网

Android 最好的方法:节省和;恢复ScrollView中的TextView位置

Android 最好的方法:节省和;恢复ScrollView中的TextView位置,android,android-layout,textview,android-orientation,android-scrollview,Android,Android Layout,Textview,Android Orientation,Android Scrollview,我想要的是,当设备改变方向时,纵向屏幕上的顶线仍然是横向屏幕上的顶线。反之亦然 由于纵向和横向屏幕的宽度可能不同,因此文本的线宽(也就是TextView和ScrollView的宽度)会有所不同。因此,在不同的屏幕配置(纵向与横向、大屏幕与小屏幕)中,换行将不同。在不同的情况下,断线将位于不同的位置 有三个不太完美的解决方案供您参考。也解释了它们的缺点 首先,最基本的方法是: (1) 只需以像素为单位存储y偏移 请看: 为什么这不是那么完美: 在肖像画中,线条被包裹 Line_1_Word_A

我想要的是,当设备改变方向时,纵向屏幕上的顶线仍然是横向屏幕上的顶线。反之亦然

由于纵向和横向屏幕的宽度可能不同,因此文本的线宽(也就是
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_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
在风景画中,线条不被包裹

想象一下,在保存的同时,在纵向中阅读
行2\u字A
(在屏幕顶部)。当更改为横向时,它将显示
行\u 3\u单词\u A
(在屏幕顶部)。(因为两条线在像素上从顶部偏移。)


然后我想出了一个方法

(2) 通过保存滚动百分比 当且仅当每条线的长度相同时,此方法才能完美工作

为什么这不是那么完美:

在肖像画中,线条被包裹

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_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
在风景画中,线条不被包裹

想象一下,在保存的同时,在纵向中阅读
行2\u字A
(在屏幕顶部)。当更改为横向时,它将显示
行\u 3\u单词\u A
(在屏幕顶部)。(因为它滚动了50%。)


然后我发现这个方法确实

(3) 存储第一个可见行 请看(第一个答案):

为什么这不是那么完美:

在肖像画中,线条被包裹

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_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
在风景画中,线条不被包裹

想象一下,在保存时,在纵向中阅读
行1\u单词E
(在屏幕顶部)。当更改为横向时,它将显示
行\u 3\u单词\u A
(在屏幕顶部)。(因为这是第三行。)

一个完美的方法是,在横向视图中,在屏幕顶部显示
行单词A
(以及
行单词E


你能建议一个完美的方法吗


编辑: 经过几番思考,方法(3)与方法(1)实际上是相同的吗-/


编辑2: 好吧,我刚刚提出了另一种不太完美但比上述三种更完美的方法:

(4) 基于段落的存储 将段落(或文本块)分隔为不同的TextView对象

然后,通过类似方法(3)的代码或任何其他方式,不难检测当前屏幕顶部的段落(或块),即哪个TextView对象

然后还原并向下滚动到该段落(或块)。宾果

正如我所说,它并不完美。但至少用户可以回到他/她正在阅读的段落(或区块)。他/她只需往下看一眼就可以找到那一行。(或者最好用前面几行来提醒读者,即从段落的开头开始阅读。)我知道如果我们有一个很长的段落,可能会非常糟糕:-/

实际上,我们可以“改进”这种方法。把它降到单词级,一个单词一个文本视图。因此,它在逻辑上是“完美的”。但是,我想,这不是一个明智的选择

洗手间总是头脑风暴的最佳场所(-:



我仍然在寻找你的完美答案!!我很自豪地说,我现在找到了一个完美的解决方案

Sh…(对不起,我对此太激动了。如果您发现任何错误/bug/弱点,请给我您的宝贵建议,并请随时纠正我。:-)

少说废话,给你

@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);
        }
    });
}
就这样。:-)


如果对你有帮助,请拍手。取最小android设备的像素密度,然后乘以设备的纵向宽度。然后计算出适合该行的单词数,并相应地换行(您可能希望将其保存并在
onrestoreinnstancestate()
中使用)。您希望在纵向和横向中实现相同的换行-对吗?感谢@g00dy的回复。但在大多数情况下,纵向和横向的线条环绕(水平宽度)并不相同。如果是相同的,我们没有头痛:-)是的,我理解:-)但是我仍然不确定你是否想要相同的线包装用于纵向和横向-请首先确认。相同的线包装是否意味着在每条线的同一点断线?对于这一点,不。@midnite:我的解决方案考虑是否在顶部显示部分线,并将其恢复,以便在旋转后再次显示相同部分的线。如果第一行是完全可见的,它反而(重新)存储可见的顶部填充部分。我喜欢你的热情!你为什么不直接用getScrollY呢?谢谢隐马尔可夫模型。。。AFAI大多数文本(网页除外)只是垂直滚动。修改这些代码来处理水平滚动也不难:)
ScrollView
(以及任何与此相关的视图)必须有一个id才能被Android持久化。你不应该这么做。在scrollview中添加id将强制android保存/恢复其状态,包括滚动位置。看看这个:这也适用于
NestedScrollView
@dnkoutso:当定义
@+id
强制Android保持滚动位置时,它不考虑单词包装@midnite解决方案几乎完美地工作(由于文本重新排列,出现了一些像素脱落,但并不严重)。