gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:00:32 24 4
gpt4 key购买 nike

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

但是我需要使用 StaticLayout 来处理一些应用了一些可跨越的“内容”的文本。

    layoutBpm = new StaticLayout(bpmValue,
textPaintBPM, arcRadius, Layout.Alignment.ALIGN_NORMAL, 0, 1,
false);

layoutBpm.draw(canvas);

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

我似乎找不到任何我能理解的文档来解释 StaticLayout 的一些参数实际上做了什么(float spacingmult?float spacingadd?),但我认为第三个是 StaticLayout 文本的最大宽度我只能从 onMeasure 获取,因为它与我的 Canvas 大小有关。这让我想将作业放在 onMeasure 或 onDraw 中,这两者似乎都不是我想要做的。将 StaticLayout 赋值放在 onDraw 中是否可以,或者有更好的方法吗?

希望这是有道理的,我对此很陌生。感谢您的任何帮助。

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

最佳答案

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

StaticLayout 的情况下,您只需要在文本更改或调整 padding、spacing 或 maxwidth 时创建一个新布局。如果文本经常更改,那么您可能需要考虑 DynamicLayout,它每次都会重新测量自己。与创建新对象相比,重新测量成本更高,但它发生的频率没有比 onDraw() 调用更频繁的了。

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

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

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

编辑:

跳过测量过程的一种方法是在新调整大小的 View 本身上调用 View#measure。所以你的 createLayout() 方法应该是这样的。

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

基本上,它所做的是告诉布局 View 可以达到的最大值。它会测量自己和它的 child 。 forceLayout() 将在父级(您的自定义 View )上调用,父级将根据新测量值重新布局其他内容。

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

希望对您有所帮助。

关于android - 避免在 onDraw() (StaticLayout) 中分配对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17092887/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com