2008年12月4日星期四

Flex Bottom Bleeding DataGrid   [+/-]

Ticore's Blog

承上次 Flex 不規則底部形狀的 DataGrid
這次公布解答,跟大家說明一下做法

其實 ListBase 系列的組件有一個屬性可用 offscreenExtraRowsOrColumns
ListBase 組件為了節省資源,只會產生畫面上呈現必要的 Item 數量
這個屬性就是用來控制畫面外要多產生幾個 Item
單純增加 offscreenExtraRowsOrColumns 數量是看不出來效果的
因為 ListBase 區域外的東西都會被遮罩遮掉

看到這裡應該有一些線索了吧
配合使用 offscreenExtraRowsOrColumns 屬性
再修改 Mask 行為,就可以讓 DataGrid 做到出血的功能了

什麼,還是看不懂我的意思?
那直接看 Code 好了~~

BleedingDataGrid:

package {
 import flash.display.DisplayObject;
 import flash.geom.Rectangle;
 
 import mx.controls.DataGrid;
 import mx.core.mx_internal;

 use namespace mx_internal;
 public class BleedingDataGrid extends DataGrid {
  
  [Bindable]
  public var bottomBleed:int = 0;
  
  public function BleedingDataGrid() {
   super();
   this.offscreenExtraRowsOrColumns = 3;
  }
  
  override protected function createChildren():void {
   super.createChildren();
   this.listContent.blendMode = "layer";
  }
  
  override protected function updateDisplayList(
        unscaledWidth:Number, unscaledHeight:Number):void {
   var h:int = unscaledHeight - viewMetrics.top - viewMetrics.bottom;
   if (bottomBleed < 0) {
    // Reduced ScrollBar Mode
    super.updateDisplayList(unscaledWidth, unscaledHeight +
      ((h + bottomBleed <= minHeight) ? 0 : bottomBleed));
    maskShape.height = h;
   } else {
    // Bleeding Content Mode
    super.updateDisplayList(unscaledWidth, unscaledHeight);
    maskShape.height = (h <= minHeight) ? h : h + bottomBleed;
   }
  }
  
  override protected function adjustListContent(
        unscaledWidth:Number = -1, unscaledHeight:Number = -1):void {
   super.adjustListContent(unscaledWidth, unscaledHeight);
   var itemClass:Class = itemRenderer["generator"];
   var topOffset:int = listContent.topOffset;
   var child:DisplayObject, i:int;
   
   // Force top offscreen selectionLayer invisible
   for (i = 0 ; i < selectionLayer.numChildren ; ++i) {
    child = selectionLayer.getChildAt(i);
    //trace(child.y, listContent.y, headerHeight, topOffset);
    child.visible = (child.y < Math.abs(topOffset) && topOffset < 0) ? false : true;
   }
   
   // Force top offscreen ItemRenderer invisible
   for (i = 0 ; i < listContent.numChildren ; ++i) {
    child = listContent.getChildAt(i);
    if (child is itemClass) {
     // trace(child.y, listContent.y, headerHeight, topOffset);
     // Warning, use visible property will cause item position disorder!
     child.alpha = (child.y < Math.abs(topOffset) && topOffset < 0) ? 0 : 1;
     // Another way to make it invisible
     // child.scrollRect = (child.y < Math.abs(topOffset) && topOffset < 0) ? new Rectangle() : null;
    }
   }
  }
  
 }
}
// Ticore's Blog - http://ticore.blogspot.com

BleedingModeDataGrid.mxml:

<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" fontSize="12" backgroundColor="#F0F0F0">
 <mx:Panel title="BleendingDataGrid - Bleeding Content Mode" height="100%" width="100%" layout="absolute">
  <local:BleedingDataGrid xmlns:local="*" id="dg" width="100%" height="100%"
    dataProvider="{employees}" borderStyle="none" top="0" bottom="50" bottomBleed="50">
   <local:columns>
    <mx:DataGridColumn dataField="name" headerText="Name"/>
    <mx:DataGridColumn dataField="phone" headerText="Phone"/>
    <mx:DataGridColumn dataField="email" headerText="Email"/>
   </local:columns>
  </local:BleedingDataGrid>
  <mx:Canvas width="100%" height="50" bottom="0" backgroundSize="100%" alpha=".9"
    filters="{[new BevelFilter(4, 90, 0xFFFFFF, 1, 0x0, 1, 10, 10, 1.6, 2), new DropShadowFilter(3, 270, 0, 1, 0, 5, 0.3, 2)]}"
    backgroundImage="@Embed(source='../assets/BottomSkin.swf', symbol='assets.BottomSkin')">
   <mx:Button label="Button" right="10" verticalCenter="0" />
  </mx:Canvas>
  <mx:ControlBar paddingTop="5" paddingBottom="5" horizontalAlign="right">
   <mx:Text><mx:htmlText>
    <![CDATA[ <u><a href="http://ticore.blogspot.com">Ticore's Blog - http://ticore.blogspot.com</a></u> ]]>
   </mx:htmlText></mx:Text>
  </mx:ControlBar>
 </mx:Panel>
 
 <mx:XMLList id="employees">
  <employee>
   <name>Christina Coenraets</name>
   <phone>555-219-2270</phone>
   <email>ccoenraets@fictitious.com</email>
  </employee>
  <employee>
   <name>Joanne Wall</name>
   <phone>555-219-2012</phone>
   <email>jwall@fictitious.com</email>
  </employee>
  <employee>
   <name>Maurice Smith</name>
   <phone>555-219-2012</phone>
   <email>maurice@fictitious.com</email>
  </employee>
  <employee>
   <name>Mary Jones</name>
   <phone>555-219-2000</phone>
   <email>mjones@fictitious.com</email>
  </employee>
  <employee>
   <name>Christina Coenraets</name>
   <phone>555-219-2270</phone>
   <email>ccoenraets@fictitious.com</email>
  </employee>
  <employee>
   <name>Joanne Wall</name>
   <phone>555-219-2012</phone>
   <email>jwall@fictitious.com</email>
  </employee>
  <employee>
   <name>Maurice Smith</name>
   <phone>555-219-2012</phone>
   <email>maurice@fictitious.com</email>
  </employee>
  <employee>
   <name>Mary Jones</name>
   <phone>555-219-2000</phone>
   <email>mjones@fictitious.com</email>
  </employee>
  <employee>
   <name>Christina Coenraets</name>
   <phone>555-219-2270</phone>
   <email>ccoenraets@fictitious.com</email>
  </employee>
  <employee>
   <name>Joanne Wall</name>
   <phone>555-219-2012</phone>
   <email>jwall@fictitious.com</email>
  </employee>
  <employee>
   <name>Maurice Smith</name>
   <phone>555-219-2012</phone>
   <email>maurice@fictitious.com</email>
  </employee>
  <employee>
   <name>Mary Jones</name>
   <phone>555-219-2000</phone>
   <email>mjones@fictitious.com</email>
  </employee>
 </mx:XMLList>
</mx:Application>

底部出血 DataGrid 線上範例:

其實除了讓 DataGrid 出血之外
還有另一種做法,讓 DataGrid 捲軸內縮
以上的 BleedingDataGrid Class 已經考慮到這種模式
使用的時候只需要將 bottomBleed 設為負值就可以了

ReducedModeDataGrid.mxml:

<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" fontSize="12" backgroundColor="#F0F0F0">
 <mx:Panel title="BleendingDataGrid - Reduced ScrollBar Mode" height="100%" width="100%" layout="absolute">
  <local:BleedingDataGrid xmlns:local="*" id="dg" width="100%" height="100%"
    dataProvider="{employees}" borderStyle="none" bottom="0" bottomBleed="-50">
   <local:columns>
    <mx:DataGridColumn dataField="name" headerText="Name"/>
    <mx:DataGridColumn dataField="phone" headerText="Phone"/>
    <mx:DataGridColumn dataField="email" headerText="Email"/>
   </local:columns>
  </local:BleedingDataGrid>
  <mx:Canvas width="100%" height="50" bottom="0" backgroundSize="100%" alpha=".9"
    filters="{[new BevelFilter(4, 90, 0xFFFFFF, 1, 0x0, 1, 10, 10, 1.6, 2), new DropShadowFilter(3, 270, 0, 1, 0, 5, 0.3, 2)]}"
    backgroundImage="@Embed(source='../assets/BottomSkin.swf', symbol='assets.BottomSkin')">
   <mx:Button label="Button" right="10" verticalCenter="0" />
  </mx:Canvas>
  <mx:ControlBar paddingTop="5" paddingBottom="5" horizontalAlign="right">
   <mx:Text><mx:htmlText>
    <![CDATA[ <u><a href="http://ticore.blogspot.com">Ticore's Blog - http://ticore.blogspot.com</a></u> ]]>
   </mx:htmlText></mx:Text>
  </mx:ControlBar>
 </mx:Panel>
 
 <mx:XMLList id="employees">
  <employee>
   <name>Christina Coenraets</name>
   <phone>555-219-2270</phone>
   <email>ccoenraets@fictitious.com</email>
  </employee>
  <employee>
   <name>Joanne Wall</name>
   <phone>555-219-2012</phone>
   <email>jwall@fictitious.com</email>
  </employee>
  <employee>
   <name>Maurice Smith</name>
   <phone>555-219-2012</phone>
   <email>maurice@fictitious.com</email>
  </employee>
  <employee>
   <name>Mary Jones</name>
   <phone>555-219-2000</phone>
   <email>mjones@fictitious.com</email>
  </employee>
  <employee>
   <name>Christina Coenraets</name>
   <phone>555-219-2270</phone>
   <email>ccoenraets@fictitious.com</email>
  </employee>
  <employee>
   <name>Joanne Wall</name>
   <phone>555-219-2012</phone>
   <email>jwall@fictitious.com</email>
  </employee>
  <employee>
   <name>Maurice Smith</name>
   <phone>555-219-2012</phone>
   <email>maurice@fictitious.com</email>
  </employee>
  <employee>
   <name>Mary Jones</name>
   <phone>555-219-2000</phone>
   <email>mjones@fictitious.com</email>
  </employee>
  <employee>
   <name>Christina Coenraets</name>
   <phone>555-219-2270</phone>
   <email>ccoenraets@fictitious.com</email>
  </employee>
  <employee>
   <name>Joanne Wall</name>
   <phone>555-219-2012</phone>
   <email>jwall@fictitious.com</email>
  </employee>
  <employee>
   <name>Maurice Smith</name>
   <phone>555-219-2012</phone>
   <email>maurice@fictitious.com</email>
  </employee>
  <employee>
   <name>Mary Jones</name>
   <phone>555-219-2000</phone>
   <email>mjones@fictitious.com</email>
  </employee>
 </mx:XMLList>
</mx:Application>

捲軸內縮 DataGrid 線上範例:

相關連結:
Flex Bottom Bleeding DataGrid 2
Flex DataGrid Header and Column Bgs Bug
DataGrid offscreenExtraRowsOrColumns Bug
Flex 不規則底部形狀的 DataGrid

Read more...