首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在onDraw() (StaticLayout)中避免对象分配?

在onDraw() (StaticLayout)中避免对象分配?
EN

Stack Overflow用户
提问于 2013-06-14 01:00:19
回答 1查看 3.5K关注 0票数 6

我有一个自定义视图,我很快就学会了不在其中进行对象分配,并将所有的绘图分配都移到了一个不同的方法中,很好。

我需要使用一个StaticLayout,然而,对于一些应用了一些可跨转的‘东西’的文本。

代码语言:javascript
复制
    layoutBpm = new StaticLayout(bpmValue,
            textPaintBPM, arcRadius, Layout.Alignment.ALIGN_NORMAL, 0, 1,
            false);

    layoutBpm.draw(canvas);

这对我来说在onDraw中似乎是有意义的,但我当然被警告要避免这样做。对我来说,尽我所能避免任何性能问题是很重要的,所以我正在努力做到这一点。

我似乎找不到任何我能理解的文档来解释StaticLayout的一些参数实际上是做什么的(浮动间隔what?浮动间距as?),但第三个我认为是StaticLayout文本的最大宽度,我只能从onMeasure获得,因为它与我的画布大小有关。这使得我想把赋值放在onMeasure或onDraw中,这似乎不是我想要做的。是否可以将StaticLayout赋值放在onDraw中,或者是否有更好的方法来这样做?

希望这是有意义的,我对此非常陌生。谢谢你的帮助。

(编辑:我假设将这个赋值放在一个方法中并从onDraw/onMeasure调用是愚蠢的,并且会停止Eclipse警告我,但实际上不会有帮助?)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-06-14 01:57:04

该警告的原因是,通常情况下,您不需要在绘制操作中多次重新创建对象。与View中的其他方法相比,onDraw()可以被调用数百次。大多数情况下,正在重新创建的对象是使用确切的参数重新创建的。其他时候,与创建新对象相比,更改对象状态的开销更小。

对于StaticLayout,您只需在文本更改或调整填充、间距或最大宽度时创建一个新的。如果文本经常更改,那么您可能需要考虑每次都会重新测量自身的DynamicLayout。与创建新对象相比,重新测量的开销更大,但它发生的频率不会比onDraw()调用更高。

如果文本不经常更改,并且您绝对必须使用StaticLayout,那么您可以使用类似这样的结构。

代码语言:javascript
复制
StaticLayout myLayout;
String textSource = defaultSource;
Paint textPaint = defaultPaint;
int textWidth = defaultWidth; 

public CustomView(Context ctx) {
    super(ctx);
    createLayout();
}

public void setText(String text) {
   textSource = text;
   createLayout();
}

public void setWidth(int width) {
   textWidth = width;
   createLayout();
}

@Override
public void onDraw(Canvas canvas) {
   myLayout.draw(canvas);
}

private void createLayout() {
   myLayout = new StaticLayout(textSource, textPaint, textWidth, Layout.Alignment.ALIGN_NORMAL, 0, 1, false);
}

基本上,只有在某些情况发生变化时才会创建新布局。否则,您只需重用您创建的最后一个对象。

EDIT:

跳过度量传递的一种方法是对新调整大小的视图本身调用View#measure。所以你的createLayout()方法应该是这样的。

代码语言:javascript
复制
   private void createLayout() {
       myLayout = new StaticLayout(textSource, textPaint, textWidth, Layout.Alignment.ALIGN_NORMAL, 0, 1, false);
       int textWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth, MeasureSpec.AT_MOST);
       int textHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight, MeasureSpec.AT_MOST);
       myLayout.measure(textWidthSpec, textHeightSpec);
       forceLayout();
    }

基本上,这样做是告诉布局视图可以达到的最大值。它会测量自己和它的子代。将在父视图(您的自定义视图)上调用forceLayout(),它将根据新的测量结果重新布局其他内容。

我应该注意的是,我从来没有用StaticLayout做过这件事,所以我不知道会发生什么。似乎在创建视图时,这种类型的度量可能已经被处理了,但也可能没有。

我希望这能帮到你。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17092887

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档