最好的方式,储存并恢复在滚动型TextView的位置 [英] Best Way: Save & Restore TextView Position in ScrollView

查看:180
本文介绍了最好的方式,储存并恢复在滚动型TextView的位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要的是,在设备改变方向,屏幕上的第一行以人像保留在屏幕上线景观。反之亦然。

What i want is, upon the device changes orientation, the top line on the screen when in Portrait remains the top line on screen in Landscape. And vice versa.

由于屏幕的宽度很可能是人像和风景,文字的线宽,这也意味着的宽度的TextView 和<之间的不同code>滚动型,会有所不同。因此,行包将在不同的屏幕配置的不同(肖像与风景,大与小)。该系列产品突破将在不同的情况下,不同的位置。

As the width of the screen is likely to be different between Portrait and Landscape, the line width of the text, which means also the width of the TextView and the ScrollView, will vary. Thus, the line-wrap will be different in different screen configurations (Portrait vs. Landscape, large vs. small). The line-break will be at different position in different cases.

有三种的不那么完美作为您的参考解决方案。还解释他们的缺点。

There are three not-so-perfect solutions for your reference. Also explained the shortcomings of them.

首先,很大部分基本方法:

Firstly, The very most basic approach:

请看看:<一href="http://eliasbland.word$p$pss.com/2011/07/28/how-to-save-the-position-of-a-scrollview-when-the-orientation-changes-in-android/">http://eliasbland.word$p$pss.com/2011/07/28/how-to-save-the-position-of-a-scrollview-when-the-orientation-changes-in-android/

为什么这是不那么完美的:

在肖像,线条包裹。

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

在景观,线条的没有的包裹。

In Landscape, lines are not wrapped.

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 (在屏幕顶部)。的(因为两线偏移式像素从顶部。)

Imagine reading Line_2_Word_A (at screen top) in Portrait while saving. When changed to Landscape, it will be showing Line_3_Word_A (at screen top). (Because of two-lines-offset-in-pixel from top.)

然后,我想出了一个办法,

Then i come up with an approach,

@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()));
        }
    });
}

这完美的作品的当且仅当的每一行的长度是一样的。

This works perfectly if and only if the length of every line is the same.

为什么这是不那么完美的:

在肖像,线条包裹。

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

在景观,线条的没有的包裹。

In Landscape, lines are not wrapped.

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%的滚动。)

Imagine reading Line_2_Word_A (at screen top) in Portrait while saving. When changed to Landscape, it will be showing Line_3_Word_A (at screen top). (Because it is scrolled by 50%.)

后来我发现这种方法这的确

Then i found this approach which indeed

请看看(第一个答案):<一href="http://stackoverflow.com/questions/5381964/how-to-restore-textview-scrolling-position-after-screen-rotation">How恢复的TextView滚动屏幕旋转后的位置?

Please take a look at (first answer): 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

在景观,线条的没有的包裹。

In Landscape, lines are not wrapped.

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 (在屏幕顶部)。的(由于它是第三行。)

Imagine reading Line_1_Word_E (at screen top) in Portrait while saving. When changed to Landscape, it will be showing Line_3_Word_A (at screen top). (Because it is the third line.)

一个完美的人会在景观,呈现出 Line_1_Word_A (以及 Line_1_Word_E ),在屏幕上方。

A perfect one would be, in Landscape, showing Line_1_Word_A (as well as Line_1_Word_E) at screen top.

请您提供一个完美的方式?

Could you please suggest a perfect approach?

在进行一些想法,是方法(3)相同的方法(1)中的事实? : - /

After a few thoughts, is method (3) identical to method (1) in fact? :-/

嗯,我刚刚参加了另一个的不那么完美,但-更加完美办法比上述三种:

Well, i have just come up with another not-so-perfect-yet-more-perfect approach than the above three:

分离段(或文本块)为不同的TextView对象。

Separating paragraphs (or blocks of texts) into different TextView objects.

然后由codeS类似的方法(3),或以任何其他方式,就不难发现其中段(或块),即该TextView的对象,是目前屏幕的顶部。

Then by the codes like method (3), or in any other ways, it is not hard to detect which paragraph (or block), i.e. which TextView object, is currently at the top of the screen.

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

Then restore and scroll down to that paragraph (or block). Bingo!

正如我所说的,这是 不那么完美。但至少用户可以回到那一段(或块),他/她在看书。他/她只需要向下偷看了一下,找到特定行。 (也可能是更好的,提醒读者提供了一些previous线,即从段落的开始阅读。)的我知道这可能是非常坏的,如果我们有一个很长很长很长段: - /

As i said, it is not-so-perfect. But at least the users can get back to that paragraph (or block) that he/she was reading. He/She just have to peek down a bit to find that particular line. (Or it might be even better to remind readers with a few previous lines, i.e. reading from the start of the paragraph.) i know it might be terribly bad if we have a long long long paragraph :-/

好了,我们实际上可以改善这个方法。让它降到字级,字一个TextView。因此,它在逻辑上是完美。但是,我想,这不是一个明智的选择。

Well, we can actually "improve" this method. Make it down to word-level, a word a TextView. So it is logically "perfect". But, i guess, it is not a wise choice.

P.S。浴室永远是最好的地方,头脑风暴( - :

推荐答案

嘘......(对不起IM太兴奋,如果你发现它的任何错误/错误/缺陷,请你给我你的宝贵意见,并请随时纠正我: - )

WOW WOW WOW - hey guys! i'm so proud to say, i got a PERFECT solution to this now * * * * *

Sh.... (sorry i m too excited about it. If you find any mistakes/bugs/weakness on it, please DO give me your valuable suggestions and please feel free to correct me. :-)

废话少说。在这里你去!

Cut the crap. Here you go !!!

@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);
        }
    });
}

就是这样。 : - )

That's it. :-)

如果它可以帮助你,请拍拍手。 &LT; - 这是很重要的!

If it helps you, please clap your hands. <-- this is important!!

如果你想要,点击那个小直角三角形。 (请确保您已先拍你的手!)

And if you wish to, click that little upright triangle. (make sure you have clapped your hands first!)

欢呼声中,
midnite

cheers,
midnite

这篇关于最好的方式,储存并恢复在滚动型TextView的位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆