<menu id="ocigx"><listing id="ocigx"><em id="ocigx"></em></listing></menu><em id="ocigx"><track id="ocigx"><strong id="ocigx"></strong></track></em>
<ins id="ocigx"></ins>

<samp id="ocigx"></samp>

<mark id="ocigx"><ruby id="ocigx"><legend id="ocigx"></legend></ruby></mark><bdo id="ocigx"></bdo>
      <kbd id="ocigx"></kbd>
      首頁 > 設計 > WEB開發 > 正文

      3.24.手動布局容器

      2023-08-08 22:33:06
      字體:
      來源:轉載
      供稿:網友
      3.24.1 問題
      你需要根據類型以及類型的屬性來布置容器的子組件。
      3.24.2 解決辦法
      覆蓋UIComponent 的updateDisplayList 方法來移動子組件。
      3.24.3 討論
      要在任何Container 或者UIComponent 對象內覆蓋任何布局或設置大小的邏輯,只要覆蓋updateDisplayList 方法并在super.updateDisplayList分方法之后插入你自己的布局邏輯即可。本節專注于如何通過使用子組件的自定義的屬性來決定Hbox 子組件的布局。這個例子由4 個文件組成,三個類和一個接口,它們各司其職并擁有自己獨有的屬性。大致的UML圖(圖Figure 3-1)描述了它們之間的關系。

      Figure 3-1. Relationships between containers and interfaces

      Canvas.mxml 文件內添加了ForceLayout 組件并提供其子組件。ForceLayout 組件可以包含任何子組件,但如果子組件實現了IspecialLayout 接口,ForceLayout 組件將會根據此類子組件是否被選中來進行不同的布局。SpecialLayoutCanvas 定義了簡單的方法來決是否被選中。

      首先,看一下SpecialLayoutCanvas.as 文件:
      +展開
      -ActionScript
      package oreilly.cookbook
      {
      import mx.containers.Canvas;
      import mx.controls.Label;
      import mx.core.UIComponent;
      import flash.events.MouseEvent;
      public class SpecialLayoutCanvas extends Canvas implements
      ISpecialLayout
      {
      private var titlelabel:Label;
      private var selectedlabel:Label;
      private var _isSelected:Boolean = false;
      public function SpecialLayoutCanvas()
      {
      super();
      titlelabel = new Label();
      addChild(titlelabel);
      titlelabel.text = "Label";
      this.addEventListener(MouseEvent.MOUSE_DOWN,
      setIsSelected);
      minHeight = 45;
      minWidth = 80;
      selectedlabel = new Label();
      //addChild(selectedlabel);
      selectedlabel.text = "Selected";
      }
      private function setIsSelected(mouseEvent:MouseEvent):void
      {
      _isSelected ? isSelected = false : isSelected = true;
      }
      public function set isSelected(value:Boolean):void
      {
      _isSelected = value;
      if(isSelected)
      {
      addChild(selectedlabel);
      selectedlabel.y = 30;
      }e
      else
      {
      try{
      removeChild(selectedlabel);
      }catch(err:Error){}
      }i
      if(parent != null)
      {
      (parent as UIComponent).invalidateDisplayList();
      }
      }
      public function get isSelected():Boolean
      {
      return _isSelected;
      }
      }
      }

      這個類使用getter 和setter 方法簡單地定義了一個selected 屬性,并且當對象被選中的時候給其添加一個標簽,反之刪除這個標簽。

      下一步,我們來看ForceLayout 組件,它讀取所有的子組件來判別它們中是否有繼承IspecialLayout 接口的,如果有,是否選中了。
      +展開
      -ActionScript
      package oreilly.cookbook
      {
      import mx.core.EdgeMetrics;
      import mx.core.UIComponent;
      import mx.containers.VBox;
      import mx.containers.Panel;
      import mx.containers.Canvas;
      import flash.display.DisplayObject;
      public class ForceLayout extends VBox
      {
      public var gap:Number;
      public function ForceLayout()
      {
      super();
      }

      無論何時,只要該組件需要重繪的時候,Flex 框架即調用updateDisplayList 方法。因為重繪的時候組件需要做的一件事情是重新調整所有子組件的位置,所有調整位置的邏輯都在這里實現:
      +展開
      -ActionScript
      override protected function
      updateDisplayList(unscaledWidth:Number,
      unscaledHeight:Number):void
      {
      super.updateDisplayList(unscaledWidth, unscaledHeight);
      var yPos:Number = unscaledHeight;
      // Temp variable for a container child.
      var child:UIComponent;
      var i:int = 0;
      while(i<this.numChildren)
      {
      // Get the first container child.
      child = UIComponent(getChildAt(i));
      // Determine the y coordinate of the child.
      yPos = yPos - child.height;
      // Set the x and y coordinate of the child.
      // Note that you do not change the x coordinate.
      if(child is ISpecialLayout)
      {
      if((child as ISpecialLayout).isSelected)
      {
      yPos -= 20;
      child.move(child.x, yPos);
      yPos -= 20;
      }e
      else
      {
      child.move(child.x, yPos);
      }
      }e
      else
      {
      child.move(child.x, yPos);
      // Save the y
      coordinate of the child,
      // plus the vertical gap between children.
      // This is used to calculate the coordinate
      // of the next child.
      yPos = yPos - gap;
      i++;
      }i
      = 0;
      var amountToCenter:Number = yPos / 2;
      while(i<this.numChildren)
      {
      getChildAt(i).y -= amountToCenter;
      i++;
      }
      }
      }
      }

      最后的清單將兩個組件付諸使用,將ForceLayout 容器添加到Canvas 并且添加SpecialLayoutCanvas 子組件。注意,如果它們是當前存在的,僅僅改變布局即可,不需要任何特別屬性,任何類型子組件都可以添加到ForceLayoutCanvas,并且實際上所有實現了IspecialLayout 接口的子組件都是可用的。
      +展開
      -XML
      <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxmlwidth="800"
      height="600xmlns:cookbook="oreilly.cookbook.*">

      <cookbook:ForceLayout width="400height="500"
      backgroundColor="#ffffff">

      <mx:HBox>
      <mx:Button label="button"/>
      <mx:LinkButton label="link"/>
      </mx:HBox>
      <cookbook:SpecialLayoutCanvas isSelected="false"
      backgroundColor="#c0c0cc"/>

      <mx:HBox>
      <mx:Button label="button"/>
      <mx:LinkButton label="link"/>
      </mx:HBox>
      <cookbook:SpecialLayoutCanvas isSelected="false"
      backgroundColor="#ccc0c0"/>

      <cookbook:SpecialLayoutCanvas isSelected="true"
      backgroundColor="#cc00cc"/>

      <cookbook:SpecialLayoutCanvas isSelected="false"
      backgroundColor="#ccc0c0"/>

      </cookbook:ForceLayout>
      </mx:Canvas>
      發表評論 共有條評論
      用戶名: 密碼:
      驗證碼: 匿名發表