簡體   English   中英

在Flex中,構建高度基於寬度和內容的UI組件的更好方法是什么?

[英]In Flex, what is a better way to build UI component whose height is based on width and content?

我需要構建一個基於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;
}
}

我需要構建一個基於UIComponent的新UI控件。 控件的高度應與寬度具有一定的比例,並且還取決於顯示的內容(內部文本的數量)。 有人可以推薦我該怎么做嗎?

從技術上講,你做不到。

您對Flex工作原理的整體方法/理解存在根本缺陷。

Flex組件永遠不會自行調整大小。 它始終由其父級調整大小。 measure()方法將設置理想值:measuredWidth,measuredHeight,measuredMinWidth和measuredMinHeight。 但是,它們只是提供給父容器的建議; 可能會也可能不會使用它們。

MXML掩蓋了這個概念,你的誤解很常見。

在大多數情況下,默認的Flex布局容器將盡力遵守這些值,但它們具有處理空間不足的情況的邏輯。 例如; 具有兩個子項的VGroup都設置為100%高度不會將兩個子項的大小設置為VGroup的100%。

如果沒有看到使用和調整組件大小的代碼,就很難說出發生了什么。 很可能你設置的“高度”不會被父容器覆蓋; 這是我相信這種方法有效的唯一原因。

我在這里做一些假設; 但我認為你的測量方法應該是這樣的:

override protected function measure():void
{
    super.measure();
    this.measuredwidth = text.getMeasuredOrExplicitWidth();
    this.measuredHeight = text.getMeasuredOrExplicitHeight()/heightRatio + textPadding * 2;
}

updateDisplayList(),應該是這樣的:

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

    super.updateDisplayList(unscaledWidth, unscaledHeight);

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

組件的父容器中的updateDisplayList()應該執行以下操作:

myControlInstance.height = myControlInstance.measuredHeight;
myControlInstance.width = myControlInstance.measuredWidth;

Spark框架使用所有相同的方法; 但有時候會把它們拖了一下。 因此,updateDisplayList()和measure()通常在皮膚類中; 或布局類。

根據Adobe文檔http://livedocs.adobe.com/flex/3/html/help.html?content=ascomponents_advanced_2.html,measure ()用於測量默認大小,updateDisplayList()用於調整和放置子項組件。

回答你的問題:

1)我會說什么也不做,因為你對默認大小不感興趣。

2)我認為,這並不重要,因為值更改不會立即生效(因為您將再次調用updateDisplayList)。

我的建議是有一個widthChanged事件的監聽器,並使用它計算適當的高度。 並在更改標簽時進行高度計算。

沒有辦法繞過額外的更新周期,這只是具有文本重排的布局的本質。 通常它是如何完成的(或者至少它是如何在flex組件中完成的)是首先根據它的首選寬度進行測量,如果測量沒有明確邊界的文本,這可能相當寬。 但是,此測量非常重要,因為它會在layoutBoundsWidth或layoutBoundsHeight中設置uper limit之前,如果及何時嘗試擴展寬度,則通知父容器。 一旦在第一次調用updateDisplayList中設置了邊界,就應該調整文本大小並使invalidSize()無效,這樣就可以測量第二遍的高度。 對不起我手機上沒有代碼示例。 如果你需要它們,我可以在辦公室時張貼一些。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM