【问题标题】:How to restore textview scrolling position after screen rotation?屏幕旋转后如何恢复textview滚动位置?
【发布时间】:2011-03-21 18:29:33
【问题描述】:

在我的 Android 布局中,我有一个 TextView。这个 TextView 正在显示一个相当大的可跨文本并且它能够滚动。现在,当手机旋转时,视图被销毁并创建,我必须再次 setText() TextView,将滚动位置重置为开头。

我知道我可以使用 getScrolly() 和 scrollTo() 滚动到像素位置,但是由于视图宽度的变化,行变得更长,并且位于像素位置 400 的行现在可能位于 250。所以这个不是很有帮助。

我需要一种方法在 onDestroy() 中找到 TextView 中的第一条可见行,然后让 TextView 在旋转后滚动到这段特定的文本。

有什么想法吗?

【问题讨论】:

    标签: android textview screen-rotation


    【解决方案1】:

    这是一个老问题,但我在寻找相同问题的解决方案时来到这里,所以这就是我想出的。我结合了这三个问题的答案的想法:

    我尝试仅从我的应用中提取相关代码,因此请原谅任何错误。另请注意,如果您旋转到横向并返回,它可能不会在您开始的相同位置结束。例如,说“彼得”是肖像中第一个可见的词。当您旋转到横向时,“Peter”是其行中的最后一个单词,第一个是“Larry”。当您向后旋转时,“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);
    }
    

    【讨论】:

      【解决方案2】:

      TextView 可以为你保存和恢复它的状态。如果你不能使用它,你可以禁用它并显式调用方法:

      http://developer.android.com/reference/android/widget/TextView.SavedState.html http://developer.android.com/reference/android/widget/TextView.html#onSaveInstanceState() http://developer.android.com/reference/android/widget/TextView.html#onRestoreInstanceState(android.os.Parcelable)

      【讨论】:

      • 同样的问题。 TextView 只保存像素位置,不保存文本位置。旋转后,我必须计算一个新的像素位置,以便显示与以前相同的文本。
      【解决方案3】:

      最好的答案,我通过搜索得到的。

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

      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-11
        • 1970-01-01
        • 1970-01-01
        • 2018-08-24
        • 1970-01-01
        • 2011-01-31
        相关资源
        最近更新 更多