0

UIComponent に基づいて新しい UI コントロールを構築する必要があります。コントロールの高さは、幅に対して特定の比率を持つ必要があり、表示されるコンテンツ (内部のテキストの量) にも依存します。誰も私がこれを行う方法を推奨できますか?

私はググってみましたが、すべての記事は事件について話すことを避けようとしているようです. 私の個人的な感覚では、Flex がレンダリングする方法、つまり表示リストを無効にして更新する方法は、状況に対処するには本来非効率的です。

以下は私のコードです。それはすべて正常に動作しますが、高さは updateDisplayList() 内で計算され、別の updateDisplayList() をトリガーするため、これは最も効率的な方法ではないようです。

コントロールはモバイル プロジェクト内で使用されるため、デバイスが回転すると、親のサイズが変更され、コントロールのサイズも変更する必要があります。

それで、いくつか質問があります:

  1. measure() で何をすればよいですか? 高さは実際の幅に基づいているため、コントロールの親の幅がパーセンテージで定義されているため、updateDisplayList() まで最終的な幅を取得できません。
  2. updateDisplayList() の一番最初に高さを計算するのは正しいですか? そうでない場合は、どうすればよいですか?

以下は、私が意味する例です。

import flash.text.TextField;
import flash.text.TextFieldAutoSize;

import mx.core.UIComponent;

public class MyControl extends UIComponent
{
public function MyControl()
{
    super();
}

public var textPadding:Number = 15;

public var heightRatio:Number = 1.61803398875;

private var _label:String;
private var labelChanged:Boolean = false;

public function get label():String
{
    return _label;
}

public function set label(value:String):void //can be long text with about 20-30 lines
{
    if (_label != value)
    {
        _label = value;
        labelChanged = true;

        invalidateProperties();
        invalidateSize();
        invalidateDisplayList();
    }
}

private var text:TextField;

override protected function createChildren():void
{
    super.createChildren();

    if (!text)
    {
        text = new TextField();
        text.autoSize = TextFieldAutoSize.LEFT;
        text.multiline = true;
        text.wordWrap = true;
        addChild(text);
    }
}

override protected function commitProperties():void
{
    super.commitProperties();

    if (labelChanged)
    {
        text.text = label;
        labelChanged = false;
    }
}

override protected function measure():void
{
    super.measure();

    //What should I do here?
}

override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
    text.width = unscaledWidth;

    if (text.height < unscaledWidth / heightRatio)
    {
        height = unscaledWidth / heightRatio + textPadding * 2;
    }
    else
    {
        height = text.height + textPadding * 2;
    }

    super.updateDisplayList(unscaledWidth, unscaledHeight);

    text.x = textPadding;
    text.y = textPadding;
}
}
4

3 に答える 3

0

余分な更新サイクルを回避する方法はありません。これは、テキスト リフローを使用したレイアウトの性質にすぎません。通常、それがどのように行われるか (または少なくともフレックス コンポーネントでどのように行われるか) は、最初に優先幅に基づいて測定することです。ただし、layoutBoundsWidth または layoutBoundsHeight で上限が設定される前に、可能な限り幅を広げようとする必要がある場合、親コンテナーに通知するため、この測定値は重要です。updateDisplayList への最初の呼び出しで境界が設定されたら、2 回目のパスで高さを測定できるように、テキストと invalidateSize() のサイズを変更する必要があります。申し訳ありませんが、コード例がありません。モバイルにいます。必要な場合は、オフィスにいるときに投稿できます。

于 2013-11-02T01:36:14.740 に答える