【问题标题】:Prevent other views than textview to update/redraw when setting text of textview every second每秒设置 textview 的文本时,防止 textview 以外的其他视图更新/重绘
【发布时间】:2012-10-11 02:53:27
【问题描述】:

我有一个稍微复杂的布局,包含几个自定义视图,每个视图计算他们需要多少空间等等。在这个布局的顶部,我有一个 TextView,它应该从 02:04:20 (hh:mm:ss) 开始倒计时,并且每秒更新一次。

我的问题不是更新文本,问题是当我更新文本时,我的布局中的所有视图都会重新绘制。此外,我在此布局中使用画廊,所以在交互时在文本更新时使用图库会使图库立即切换到您选择的位置(即使您正在切换到图库中的新项目)。

那么..如何在不重新绘制其他视图的情况下更新文本视图?

【问题讨论】:

  • 您需要显示您的布局文件和更新文本的代码。
  • 那我得发很多帖子了。我通过继承 SurfaceView 并手动绘制文本解决了这个问题。我知道我可以从一开始就做到这一点,但我希望我能用普通的 TextView 做我想做的事情:/

标签: android drawing textview


【解决方案1】:

如果视图的宽度是固定的并且视图的高度不会改变,则 TextView 不会使 setText() 上的整个布局无效。将布局参数android:layout_width"wrap_content" 更改为固定宽度,例如"fill_parent""100sp"

Source

/**
 * Check whether entirely new text requires a new view layout
 * or merely a new text layout.
 */

private void checkForRelayout() {
    // If we have a fixed width, we can just swap in a new text layout
    // if the text height stays the same or if the view height is fixed.

    if ((mLayoutParams.width != LayoutParams.WRAP_CONTENT ||
            (mMaxWidthMode == mMinWidthMode && mMaxWidth == mMinWidth)) &&
            (mHint == null || mHintLayout != null) &&
            (mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight() > 0)) {
        // Static width, so try making a new text layout.

        int oldht = mLayout.getHeight();
        int want = mLayout.getWidth();
        int hintWant = mHintLayout == null ? 0 : mHintLayout.getWidth();

        /*
         * No need to bring the text into view, since the size is not
         * changing (unless we do the requestLayout(), in which case it
         * will happen at measure).
         */
        makeNewLayout(want, hintWant, UNKNOWN_BORING, UNKNOWN_BORING,
                      mRight - mLeft - getCompoundPaddingLeft() - getCompoundPaddingRight(),
                      false);

        if (mEllipsize != TextUtils.TruncateAt.MARQUEE) {
            // In a fixed-height view, so use our new text layout.
            if (mLayoutParams.height != LayoutParams.WRAP_CONTENT &&
                mLayoutParams.height != LayoutParams.MATCH_PARENT) {
                invalidate();
                return;
            }

            // Dynamic height, but height has stayed the same,
            // so use our new text layout.
            if (mLayout.getHeight() == oldht &&
                (mHintLayout == null || mHintLayout.getHeight() == oldht)) {
                invalidate();
                return;
            }
        }

        // We lose: the height has changed and we have a dynamic height.
        // Request a new view layout using our new text layout.
        requestLayout();
        invalidate();
    } else {
        // Dynamic width, so we have no choice but to request a new
        // view layout with a new text layout.

        nullLayouts();
        requestLayout();
        invalidate();
    }
}

【讨论】:

  • 除此之外,如源代码所示,避免将 ellipsize 属性设置为 marquee。删除在用作由 SeekBar 驱动的时间计数器的 TextView 上由错误设置的属性会导致显着的性能改进。如果布局也有 ListView,则完全重新布局会导致一些不必要的 bindView() 调用,从而影响性能。
猜你喜欢
  • 2013-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多