如何将控制栏添加到标题栏正下方的 Flex Spark 面板组件
Posted
技术标签:
【中文标题】如何将控制栏添加到标题栏正下方的 Flex Spark 面板组件【英文标题】:How to add a controlbar to the Flex Spark Panel component just below to the title bar 【发布时间】:2012-05-16 16:27:44 【问题描述】:我正在尝试在标题栏下方的 Flex Spark 面板组件中添加一个控制栏。它是作为火花控制条的控制条工作的。为了实现它,我可以添加组件来实现它,我创建了一个皮肤和一个扩展 spark 类的 as3 类。但它不起作用。谁能帮我吗。我是火花组件的新手。我需要帮助。
皮肤:CustoPanel\src\skin\CustomPanelSkinHeaderControlBar.mxml
<?xml version="1.0" encoding="utf-8"?>
<!--
ADOBE SYSTEMS INCORPORATED
Copyright 2008 Adobe Systems Incorporated
All Rights Reserved.
NOTICE: Adobe permits you to use, modify, and distribute this file
in accordance with the terms of the license agreement accompanying it.
-->
<!--- The default skin class for a Spark Panel container.
@see spark.components.Panel
@langversion 3.0
@playerversion Flash 10
@playerversion AIR 1.5
@productversion Flex 4
-->
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
minWidth="131" minHeight="127" blendMode="normal" mouseEnabled="false"
alpha.disabled="0.5"
alpha.disabledWithControlAndHeaderBar="0.5"
alpha.disabledWithControlBar="0.5"
alpha.disabledWithHeaderBar="0.5">
<fx:Metadata>
<![CDATA[
/**
* @copy spark.skins.spark.ApplicationSkin#hostComponent
*/
/* [HostComponent("spark.components.Panel")] */
[HostComponent("customCompo.ExtPanel")]
]]>
</fx:Metadata>
<fx:Script fb:purpose="styling">
<![CDATA[
import mx.core.FlexVersion;
/* Define the skin elements that should not be colorized.
For panel, border and title background are skinned, but the content area, background, border, and title text are not. */
/* static private const exclusions:Array = ["background", "titleDisplay", "contentGroup", "controlBarGroup", "border"]; */
static private const exclusions:Array = ["background", "titleDisplay", "contentGroup", "controlBarGroup", "headerControlBarGroup", "border"];
/* exclusions before Flex 4.5 for backwards-compatibility purposes */
/* static private const exclusions_4_0:Array = ["background", "titleDisplay", "contentGroup", "controlBarGroup"]; */
static private const exclusions_4_0:Array = ["background", "titleDisplay", "contentGroup", "controlBarGroup", "headerControlBarGroup"];
/**
* @private
*/
override public function get colorizeExclusions():Array
// Since border is styleable via borderColor, no need to allow chromeColor to affect
// the border. This is wrapped in a compatibility flag since this change was added
// in Flex 4.5
if (FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_5)
return exclusions_4_0;
return exclusions;
/**
* @private
*/
override protected function initializationComplete():void
useChromeColor = true;
super.initializationComplete();
/**
* @private
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
if (getStyle("borderVisible") == true)
border.visible = true;
background.left = background.top = background.right = background.bottom = 1;
contents.left = contents.top = contents.right = contents.bottom = 1;
else
border.visible = false;
background.left = background.top = background.right = background.bottom = 0;
contents.left = contents.top = contents.right = contents.bottom = 0;
dropShadow.visible = getStyle("dropShadowVisible");
var cr:Number = getStyle("cornerRadius");
var withControls:Boolean =
(currentState == "disabledWithControlBar" ||
currentState == "normalWithControlBar");
if (cornerRadius != cr)
cornerRadius = cr;
dropShadow.tlRadius = cornerRadius;
dropShadow.trRadius = cornerRadius;
dropShadow.blRadius = withControls ? cornerRadius : 0;
dropShadow.brRadius = withControls ? cornerRadius : 0;
setPartCornerRadii(topMaskRect, withControls);
setPartCornerRadii(border, withControls);
setPartCornerRadii(background, withControls);
if (bottomMaskRect) setPartCornerRadii(bottomMaskRect, withControls);
borderStroke.color = getStyle("borderColor");
borderStroke.alpha = getStyle("borderAlpha");
backgroundFill.color = getStyle("backgroundColor");
backgroundFill.alpha = getStyle("backgroundAlpha");
super.updateDisplayList(unscaledWidth, unscaledHeight);
/**
* @private
*/
private function setPartCornerRadii(target:Rect, includeBottom:Boolean):void
target.topLeftRadiusX = cornerRadius;
target.topRightRadiusX = cornerRadius;
target.bottomLeftRadiusX = includeBottom ? cornerRadius : 0;
target.bottomRightRadiusX = includeBottom ? cornerRadius : 0;
private var cornerRadius:Number;
]]>
</fx:Script>
<s:states>
<s:State name="normal" />
<s:State name="disabled" />
<s:State name="normalWithControlBar" stateGroups="withControls" />
<s:State name="disabledWithControlBar" stateGroups="withControls" />
<s:State name="normalWithControlAndHeaderbar" stateGroups="withControls" />
<s:State name="disabledWithControlAndHeaderBar" stateGroups="withControls" />
<s:State name="normalWithHeaderBar"/>
<s:State name="disabledWithHeaderBar"/>
</s:states>
<!-- drop shadow can't be hittable so it stays sibling of other graphics -->
<!--- @private -->
<s:RectangularDropShadow id="dropShadow" blurX="20" blurY="20" alpha="0.32" distance="11"
angle="90" color="#000000" left="0" top="0" right="0" bottom="0"/>
<!-- drop shadow can't be hittable so all other graphics go in this group -->
<s:Group left="0" right="0" top="0" bottom="0">
<!-- top group mask -->
<!--- @private -->
<s:Group left="1" top="1" right="1" bottom="1" id="topGroupMask" >
<!--- @private -->
<s:Rect id="topMaskRect" left="0" top="0" right="0" bottom="0">
<s:fill>
<s:SolidColor alpha="0"/>
</s:fill>
</s:Rect>
</s:Group>
<!-- bottom group mask -->
<!--- @private -->
<s:Group left="1" top="1" right="1" bottom="1" id="bottomGroupMask"
includeIn="disabledWithControlAndHeaderBar,disabledWithControlBar,normalWithControlAndHeaderbar,normalWithControlBar">
<!--- @private -->
<s:Rect id="bottomMaskRect" left="0" top="0" right="0" bottom="0">
<s:fill>
<s:SolidColor alpha="0"/>
</s:fill>
</s:Rect>
</s:Group>
<!-- layer 1: border -->
<!--- @private -->
<s:Rect id="border" left="0" right="0" top="0" bottom="0" >
<s:stroke>
<!--- @private -->
<s:SolidColorStroke id="borderStroke" weight="1" />
</s:stroke>
</s:Rect>
<!-- layer 2: background fill -->
<!--- Defines the appearance of the PanelSkin class's background. -->
<s:Rect id="background" left="1" top="1" right="1" bottom="1">
<s:fill>
<!--- @private
Defines the PanelSkin class's background fill. The default color is 0xFFFFFF. -->
<s:SolidColor id="backgroundFill" color="#FFFFFF"/>
</s:fill>
</s:Rect>
<!-- layer 3: contents -->
<!--- Contains the vertical stack of titlebar content and controlbar. -->
<s:Group left="1" right="1" top="1" bottom="1" id="contents">
<s:layout>
<s:VerticalLayout gap="0" horizontalAlign="justify" />
</s:layout>
<!--- @private -->
<s:Group id="topGroupMaskImp" mask="topGroupMask">
<!-- layer 0: title bar fill -->
<!--- @private -->
<s:Rect id="tbFill" left="0" right="0" top="0" bottom="1">
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0xE2E2E2" />
<s:GradientEntry color="0xD9D9D9" />
</s:LinearGradient>
</s:fill>
</s:Rect>
<!-- layer 1: title bar highlight -->
<!--- @private -->
<s:Rect id="tbHilite" left="0" right="0" top="0" bottom="0">
<s:stroke>
<s:LinearGradientStroke rotation="90" weight="1">
<s:GradientEntry color="0xEAEAEA" />
<s:GradientEntry color="0xD9D9D9" />
</s:LinearGradientStroke>
</s:stroke>
</s:Rect>
<!-- layer 2: title bar divider -->
<!--- @private -->
<s:Rect id="tbDiv" left="0" right="0" bottom="0">
<s:fill>
<s:SolidColor color="0xC0C0C0" />
</s:fill>
</s:Rect>
<!-- layer 3: text -->
<!--- @copy spark.components.Panel#titleDisplay -->
<s:Label id="titleDisplay" maxDisplayedLines="1"
left="9" right="3" top="1" bottom="0" minHeight="20"
verticalAlign="middle" textAlign="start" fontWeight="bold">
</s:Label>
</s:Group>
<!--
Note: setting the minimum size to 0 here so that changes to the host component's
size will not be thwarted by this skin part's minimum size. This is a compromise,
more about it here: http://bugs.adobe.com/jira/browse/SDK-21143
-->
<!--Header ControlBar-->
<!--- @private -->
<s:Group id="topGroup" minWidth="0" minHeight="0"
includeIn="normalWithControlAndHeaderbar,disabledWithControlAndHeaderBar,normalWithHeaderBar,disabledWithHeaderBar" >
<s:Group left="0" right="0" top="0" bottom="0" mask="bottomGroupMask">
<!-- layer 0: control top bar divider line -->
<s:Rect left="0" right="0" top="0" alpha="0.22">
<s:fill>
<s:SolidColor color="0x000000" />
</s:fill>
</s:Rect>
<!-- layer 1: control top bar highlight -->
<s:Rect left="0" right="0" top="1" bottom="0">
<s:stroke>
<s:LinearGradientStroke rotation="90" weight="1">
<s:GradientEntry color="0xE5E5E5" />
<s:GradientEntry color="0xD8D8D8" />
</s:LinearGradientStroke>
</s:stroke>
</s:Rect>
<!-- layer 2: control top bar fill -->
<s:Rect left="1" right="1" top="2" bottom="1">
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0xDADADA" />
<s:GradientEntry color="0xC5C5C5" />
</s:LinearGradient>
</s:fill>
</s:Rect>
</s:Group>
<!-- layer 3: top control bar -->
<!--- @copy spark.components.Panel#controlBarTopGroup -->
<s:Group id="headerControlBarGroup" left="0" right="0" top="1" bottom="1" minWidth="0" minHeight="0">
<s:layout>
<s:HorizontalLayout paddingLeft="10" paddingRight="10" paddingTop="3" paddingBottom="3" gap="10" />
</s:layout>
</s:Group>
</s:Group>
<!--x-Header control Bar-->
<!--- @copy spark.components.SkinnableContainer#contentGroup -->
<s:Group id="contentGroup" minWidth="0" minHeight="0">
</s:Group>
<!--- @private -->
<s:Group id="bottomGroup" minWidth="0" minHeight="0"
includeIn="disabledWithControlAndHeaderBar,disabledWithControlBar,normalWithControlAndHeaderbar,normalWithControlBar" >
<s:Group left="0" right="0" top="0" bottom="0" mask="bottomGroupMask">
<!-- layer 0: control bar divider line -->
<s:Rect left="0" right="0" top="0" alpha="0.22">
<s:fill>
<s:SolidColor color="0x000000" />
</s:fill>
</s:Rect>
<!-- layer 1: control bar highlight -->
<s:Rect left="0" right="0" top="1" bottom="0">
<s:stroke>
<s:LinearGradientStroke rotation="90" weight="1">
<s:GradientEntry color="0xE5E5E5" />
<s:GradientEntry color="0xD8D8D8" />
</s:LinearGradientStroke>
</s:stroke>
</s:Rect>
<!-- layer 2: control bar fill -->
<s:Rect left="1" right="1" top="2" bottom="1">
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0xDADADA" />
<s:GradientEntry color="0xC5C5C5" />
</s:LinearGradient>
</s:fill>
</s:Rect>
</s:Group>
<!-- layer 3: control bar -->
<!--- @copy spark.components.Panel#controlBarGroup -->
<s:Group id="controlBarGroup" left="0" right="0" top="1" bottom="1" minWidth="0" minHeight="0">
<s:layout>
<s:HorizontalLayout paddingLeft="10" paddingRight="10" paddingTop="7" paddingBottom="7" gap="10" />
</s:layout>
</s:Group>
</s:Group>
</s:Group> <!--skl oph e-->
</s:Group>
</s:SparkSkin>
自定义面板类:
package customCompo
import mx.core.mx_internal;
import mx.utils.BitFlagUtil;
import spark.components.Group;
import spark.components.Panel;
import spark.layouts.supportClasses.LayoutBase;
use namespace mx_internal;
[SkinState("normalWithControlAndHeaderbar")]
[SkinState("disabledWithControlAndHeaderBar")]
[SkinState("normalWithHeaderBar")]
[SkinState("disabledWithHeaderBar")]
[AccessibilityClass(implementation="spark.accessibility.PanelAccImpl")]
public class ExtPanel extends Panel
public function ExtPanel()
super();
mx_internal static const HEADER_CONTROLBAR_PROPERTY_FLAG:uint = 1 << 0;
mx_internal static const HEADER_LAYOUT_PROPERTY_FLAG:uint = 1 << 1;
mx_internal static const HEADER_VISIBLE_PROPERTY_FLAG:uint = 1 << 2;
mx_internal var headerControlBarGroupProperties:Object = visible: true ;
public var headerControlBarGroup:Group;
//----------------------------------
// headerControlBarContent
//----------------------------------
[ArrayElementType("mx.core.IVisualElement")]
public function get headerControlBarContent():Array
if (headerControlBarGroup)
return headerControlBarGroup.getMXMLContent();
else
return headerControlBarGroupProperties.controlBarContent;
/**
* @private
*/
public function set headerControlBarContent(value:Array):void
if (headerControlBarGroup)
headerControlBarGroup.mxmlContent = value;
headerControlBarGroupProperties = BitFlagUtil.update(headerControlBarGroupProperties as uint,
HEADER_CONTROLBAR_PROPERTY_FLAG, value != null);
else
headerControlBarGroupProperties.headerControlBarContent = value;
invalidateSkinState();
//----------------------------------
// headerControlBarLayout
//----------------------------------
public function get headerControlBarLayout():LayoutBase
return (headerControlBarGroup)
? headerControlBarGroup.layout
: headerControlBarGroupProperties.layout;
/**
* @private
*/
public function set headerControlBarLayout(value:LayoutBase):void
if (headerControlBarGroup)
headerControlBarGroup.layout = value;
headerControlBarGroupProperties = BitFlagUtil.update(headerControlBarGroupProperties as uint,
HEADER_LAYOUT_PROPERTY_FLAG, true);
else
headerControlBarGroupProperties.layout = value;
//----------------------------------
// headerControlBarVisible
//----------------------------------
public function get headerControlBarVisible():Boolean
return (headerControlBarGroup)
? headerControlBarGroup.visible
: headerControlBarGroupProperties.visible;
/**
* @private
*/
public function set headerControlBarVisible(value:Boolean):void
if (headerControlBarGroup)
headerControlBarGroup.visible = value;
headerControlBarGroupProperties = BitFlagUtil.update(headerControlBarGroupProperties as uint,
HEADER_VISIBLE_PROPERTY_FLAG, value);
else
headerControlBarGroupProperties.visible = value;
invalidateSkinState();
if (skin)
skin.invalidateSize();
//--------------------------------------------------------------------------
//
// Overridden methods
//
//--------------------------------------------------------------------------
/**
* @private
*/
/*override protected function initializeAccessibility():void
if (Panel.createAccessibilityImplementation != null)
Panel.createAccessibilityImplementation(this);
*/
/**
* @private
*/
override protected function partAdded(partName:String, instance:Object):void
super.partAdded(partName, instance);
/*if (instance == titleDisplay)
titleDisplay.text = title;
else if (instance == controlBarGroup)*/
if (instance == headerControlBarGroup)
// copy proxied values from controlBarGroupProperties (if set) to contentGroup
var newHeaderControlBarGroupProperties:uint = 0;
if (headerControlBarGroupProperties.headerControlBarContent !== undefined)
headerControlBarGroup.mxmlContent = headerControlBarGroupProperties.headerControlBarContent;
newHeaderControlBarGroupProperties = BitFlagUtil.update(newHeaderControlBarGroupProperties,
HEADER_CONTROLBAR_PROPERTY_FLAG, true);
if (headerControlBarGroupProperties.layout !== undefined)
headerControlBarGroup.layout = headerControlBarGroupProperties.layout;
newHeaderControlBarGroupProperties = BitFlagUtil.update(newHeaderControlBarGroupProperties,
HEADER_LAYOUT_PROPERTY_FLAG, true);
if (headerControlBarGroupProperties.visible !== undefined)
headerControlBarGroup.visible = headerControlBarGroupProperties.visible;
newHeaderControlBarGroupProperties = BitFlagUtil.update(newHeaderControlBarGroupProperties,
HEADER_VISIBLE_PROPERTY_FLAG, true);
headerControlBarGroupProperties = newHeaderControlBarGroupProperties;
override protected function partRemoved(partName:String, instance:Object):void
super.partRemoved(partName, instance);
if (instance == headerControlBarGroup)
// copy proxied values from contentGroup (if explicitely set) to contentGroupProperties
var newHeaderControlBarGroupProperties:Object = ;
if (BitFlagUtil.isSet(controlBarGroupProperties as uint, HEADER_CONTROLBAR_PROPERTY_FLAG))
newHeaderControlBarGroupProperties.headerControlBarContent = headerControlBarGroup.getMXMLContent();
if (BitFlagUtil.isSet(controlBarGroupProperties as uint, HEADER_LAYOUT_PROPERTY_FLAG))
newHeaderControlBarGroupProperties.layout = headerControlBarGroup.layout;
if (BitFlagUtil.isSet(controlBarGroupProperties as uint, HEADER_VISIBLE_PROPERTY_FLAG))
newHeaderControlBarGroupProperties.visible = headerControlBarGroup.visible;
headerControlBarGroupProperties = newHeaderControlBarGroupProperties;
headerControlBarGroup.mxmlContent = null;
headerControlBarGroup.layout = null;
override protected function getCurrentSkinState():String
var state:String = enabled ? "normal" : "disabled";
if (headerControlBarGroup)
if (BitFlagUtil.isSet(headerControlBarGroupProperties as uint, HEADER_CONTROLBAR_PROPERTY_FLAG) &&
BitFlagUtil.isSet(headerControlBarGroupProperties as uint, HEADER_VISIBLE_PROPERTY_FLAG))
state += "WithHeaderBar";
else
if (headerControlBarGroupProperties.headerCcontrolBarContent &&
headerControlBarGroupProperties.visible)
state += "WithHeaderBar";
return state;
应用程序:
<s:HGroup horizontalAlign="center">
<customCompo:ExtPanel title="RABBIT :" skinClass="skin.CustomPanelSkinHeaderControlBar">
<customCompo:headerControlBarContent>
<s:Label text="Peacock" />
</customCompo:headerControlBarContent>
</customCompo:ExtPanel>
</s:HGroup>
【问题讨论】:
【参考方案1】:谢谢大家。我已经解决了。
扩展面板类:PanelWithHeaderBar.as
package components.panelWithHeader
import mx.core.mx_internal;
import mx.utils.BitFlagUtil;
import spark.components.Group;
import spark.components.Panel;
import spark.layouts.supportClasses.LayoutBase;
use namespace mx_internal;
public class PanelWithHeaderBar extends Panel
mx_internal static const HEADERBAR_PROPERTY_FLAG:uint = 1 << 0;
mx_internal var headerBarGroupProperties:Object = visible: true ;
/*Adding headerBar optional skin part */
[SkinPart(required="false")]
public var headerBarGroup:Group;
public function PanelWithHeaderBar()
super();
/*Adding new headerBar field indicating if panel adds headerBar (invalidating skin state in setter)*/
public function get headerBarContent():Array
if (headerBarGroup)
return headerBarGroup.getMXMLContent();
else
return headerBarGroupProperties.headerBarContent;
public function set headerBarContent(value:Array):void
if (headerBarGroup)
headerBarGroup.mxmlContent = value;
headerBarGroupProperties = BitFlagUtil.update(headerBarGroupProperties as uint,
CONTROLBAR_PROPERTY_FLAG, value != null);
else
headerBarGroupProperties.headerBarContent = value;
invalidateSkinState();
/* Header Bar Layout*/
public function get headerbarLayout():LayoutBase
return (headerBarGroup)
? headerBarGroup.layout
: headerBarGroupProperties.layout;
/**
* @private
*/
public function set headerbarLayout(value:LayoutBase):void
if (headerBarGroup)
headerBarGroup.layout = value;
headerBarGroupProperties = BitFlagUtil.update(headerBarGroupProperties as uint,
LAYOUT_PROPERTY_FLAG, true);
else
headerBarGroupProperties.layout = value;
/* Header Bar Visiblity*/
public function get headerBarVisible():Boolean
return (headerBarGroup)
? headerBarGroup.visible
: headerBarGroupProperties.visible;
/**
* @private
*/
public function set headerBarVisible(value:Boolean):void
if (headerBarGroup)
headerBarGroup.visible = value;
headerBarGroupProperties = BitFlagUtil.update(headerBarGroupProperties as uint,
VISIBLE_PROPERTY_FLAG, value);
else
headerBarGroupProperties.visible = value;
invalidateSkinState();
if (skin)
skin.invalidateSize();
/*Overriding partAdded()/partRemoved() functions to add headerBar event handler */
override protected function partAdded(partName:String, instance:Object):void
super.partAdded(partName, instance);
if (instance == headerBarGroup)
// copy proxied values from controlBarGroupProperties (if set) to contentGroup
var newHeaderBarGroupProperties:uint = 0;
if (headerBarGroupProperties.headerBarContent !== undefined)
headerBarGroup.mxmlContent = headerBarGroupProperties.headerBarContent;
newHeaderBarGroupProperties = BitFlagUtil.update(newHeaderBarGroupProperties,
CONTROLBAR_PROPERTY_FLAG, true);
if (headerBarGroupProperties.layout !== undefined)
headerBarGroup.layout = headerBarGroupProperties.layout;
newHeaderBarGroupProperties = BitFlagUtil.update(newHeaderBarGroupProperties,
LAYOUT_PROPERTY_FLAG, true);
if (headerBarGroupProperties.visible !== undefined)
headerBarGroup.visible = headerBarGroupProperties.visible;
newHeaderBarGroupProperties = BitFlagUtil.update(newHeaderBarGroupProperties,
VISIBLE_PROPERTY_FLAG, true);
headerBarGroupProperties = newHeaderBarGroupProperties;
/**
* @private
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
override protected function partRemoved(partName:String, instance:Object):void
super.partRemoved(partName, instance);
if (instance == headerBarGroup)
// copy proxied values from contentGroup (if explicitely set) to contentGroupProperties
var newHeaderBarGroupProperties:Object = ;
if (BitFlagUtil.isSet(headerBarGroupProperties as uint, HEADERBAR_PROPERTY_FLAG))
newHeaderBarGroupProperties.headerBarContent = headerBarGroup.getMXMLContent();
if (BitFlagUtil.isSet(headerBarGroupProperties as uint, LAYOUT_PROPERTY_FLAG))
newHeaderBarGroupProperties.layout = headerBarGroup.layout;
if (BitFlagUtil.isSet(headerBarGroupProperties as uint, VISIBLE_PROPERTY_FLAG))
newHeaderBarGroupProperties.visible = headerBarGroup.visible;
headerBarGroupProperties = newHeaderBarGroupProperties;
headerBarGroup.mxmlContent = null;
headerBarGroup.layout = null;
/**
* @private
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
override protected function getCurrentSkinState():String
var state:String = enabled ? "normal" : "disabled";
if (headerBarGroup)
if (BitFlagUtil.isSet(headerBarGroupProperties as uint, HEADERBAR_PROPERTY_FLAG) &&
BitFlagUtil.isSet(headerBarGroupProperties as uint, VISIBLE_PROPERTY_FLAG))
state += "WithHeaderBar";
else
if (headerBarGroupProperties.headerBarContent &&
headerBarGroupProperties.visible)
state += "WithHeaderBar";
if (controlBarGroup)
if (BitFlagUtil.isSet(controlBarGroupProperties as uint, CONTROLBAR_PROPERTY_FLAG) &&
BitFlagUtil.isSet(controlBarGroupProperties as uint, VISIBLE_PROPERTY_FLAG))
state += "WithControlBar";
else
if (controlBarGroupProperties.controlBarContent &&
controlBarGroupProperties.visible)
state += "WithControlBar";
return state;
面板皮肤:PanelWithHeaderBarSkin.mxml
<?xml version="1.0" encoding="utf-8"?>
<!--
ADOBE SYSTEMS INCORPORATED
Copyright 2008 Adobe Systems Incorporated
All Rights Reserved.
NOTICE: Adobe permits you to use, modify, and distribute this file
in accordance with the terms of the license agreement accompanying it.
-->
<!--- The default skin class for a Spark Panel container.
@see spark.components.Panel
@langversion 3.0
@playerversion Flash 10
@playerversion AIR 1.5
@productversion Flex 4
-->
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009" blendMode="normal" mouseEnabled="false"
minWidth="131" minHeight="127" alpha.disabled="0.5" alpha.disabledWithControlBar="0.5">
<fx:Metadata>[HostComponent("components.panelWithHeader.PanelWithHeaderBar")]</fx:Metadata>
<fx:Script fb:purpose="styling">
/* Define the skin elements that should not be colorized.
For panel, border and title background are skinned, but the content area and title text are not. */
static private const exclusions:Array = ["background", "titleDisplay", "contentGroup", "controlBarGroup", "headerBarGroup"];
/**
* @private
*/
override public function get colorizeExclusions():Array return exclusions;
/**
* @private
*/
override protected function initializationComplete():void
useChromeColor = true;
super.initializationComplete();
/**
* @private
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
if (getStyle("borderVisible") == true)
border.visible = true;
background.left = background.top = background.right = background.bottom = 1;
contents.left = contents.top = contents.right = contents.bottom = 1;
else
border.visible = false;
background.left = background.top = background.right = background.bottom = 0;
contents.left = contents.top = contents.right = contents.bottom = 0;
dropShadow.visible = getStyle("dropShadowVisible");
var cr:Number = getStyle("cornerRadius");
var withControls:Boolean =
(currentState == "disabledWithControlBar" ||
currentState == "normalWithControlBar"||
currentState == "disabledWithHeaderBar" ||
currentState == "normalWithHeaderBar" ||
currentState == "disabledWithHeaderBarWithControlBar" ||
currentState == "normalWithHeaderBarWithControlBar");
if (cornerRadius != cr)
cornerRadius = cr;
dropShadow.tlRadius = cornerRadius;
dropShadow.trRadius = cornerRadius;
dropShadow.blRadius = withControls ? cornerRadius : 0;
dropShadow.brRadius = withControls ? cornerRadius : 0;
setPartCornerRadii(topMaskRect, withControls);
setPartCornerRadii(border, withControls);
setPartCornerRadii(background, withControls);
if (bottomMaskRect) setPartCornerRadii(bottomMaskRect, withControls);
borderStroke.color = getStyle("borderColor");
borderStroke.alpha = getStyle("borderAlpha");
backgroundFill.color = getStyle("backgroundColor");
backgroundFill.alpha = getStyle("backgroundAlpha");
super.updateDisplayList(unscaledWidth, unscaledHeight);
/**
* @private
*/
private function setPartCornerRadii(target:Rect, includeBottom:Boolean):void
target.topLeftRadiusX = cornerRadius;
target.topRightRadiusX = cornerRadius;
target.bottomLeftRadiusX = includeBottom ? cornerRadius : 0;
target.bottomRightRadiusX = includeBottom ? cornerRadius : 0;
private var cornerRadius:Number;
</fx:Script>
<s:states>
<s:State name="normal" />
<s:State name="disabled" />
<s:State name="normalWithControlBar" stateGroups="withControls" />
<s:State name="disabledWithControlBar" stateGroups="withControls" />
<s:State name="normalWithHeaderBar" stateGroups="withControls" />
<s:State name="disabledWithHeaderBar" stateGroups="withControls" />
<s:State name="normalWithHeaderBarWithControlBar" stateGroups="withControls" />
<s:State name="disabledWithHeaderBarWithControlBar" stateGroups="withControls" />
</s:states>
<!-- drop shadow can't be hittable so it stays sibling of other graphics -->
<!--- @private -->
<s:RectangularDropShadow id="dropShadow" blurX="20" blurY="20" alpha="0.32" distance="11"
angle="90" color="#000000" left="0" top="0" right="0" bottom="0"/>
<!-- drop shadow can't be hittable so all other graphics go in this group -->
<s:Group left="0" right="0" top="0" bottom="0">
<!-- top group mask -->
<!--- @private -->
<s:Group left="1" top="1" right="1" bottom="1" id="topGroupMask" >
<!--- @private -->
<s:Rect id="topMaskRect" left="0" top="0" right="0" bottom="0">
<s:fill>
<s:SolidColor alpha="0"/>
</s:fill>
</s:Rect>
</s:Group>
<!-- bottom group mask -->
<!--- @private -->
<s:Group left="1" top="1" right="1" bottom="1" id="bottomGroupMask"
includeIn="normalWithControlBar, disabledWithControlBar">
<!--- @private -->
<s:Rect id="bottomMaskRect" left="0" top="0" right="0" bottom="0">
<s:fill>
<s:SolidColor alpha="0"/>
</s:fill>
</s:Rect>
</s:Group>
<!-- layer 1: border -->
<!--- @private -->
<s:Rect id="border" left="0" right="0" top="0" bottom="0" >
<s:stroke>
<!--- @private -->
<s:SolidColorStroke id="borderStroke" weight="1" />
</s:stroke>
</s:Rect>
<!-- layer 2: background fill -->
<!--- Defines the appearance of the PanelSkin class's background. -->
<s:Rect id="background" left="1" top="1" right="1" bottom="1">
<s:fill>
<!--- @private
Defines the PanelSkin class's background fill. The default color is 0xFFFFFF. -->
<s:SolidColor id="backgroundFill" color="#FFFFFF"/>
</s:fill>
</s:Rect>
<!-- layer 3: contents -->
<!--- Contains the vertical stack of titlebar content and controlbar. -->
<s:Group left="1" right="1" top="1" bottom="1" id="contents">
<s:layout>
<s:VerticalLayout gap="0" horizontalAlign="justify" />
</s:layout>
<!--- @private -->
<s:Group id="topGroup" mask="topGroupMask">
<!-- layer 0: title bar fill -->
<!--- @private -->
<s:Rect id="tbFill" left="0" right="0" top="0" bottom="1">
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0xE2E2E2" />
<s:GradientEntry color="0xD9D9D9" />
</s:LinearGradient>
</s:fill>
</s:Rect>
<!-- layer 1: title bar highlight -->
<!--- @private -->
<s:Rect id="tbHilite" left="0" right="0" top="0" bottom="0">
<s:stroke>
<s:LinearGradientStroke rotation="90" weight="1">
<s:GradientEntry color="0xEAEAEA" />
<s:GradientEntry color="0xD9D9D9" />
</s:LinearGradientStroke>
</s:stroke>
</s:Rect>
<!-- layer 2: title bar divider -->
<!--- @private -->
<s:Rect id="tbDiv" left="0" right="0" bottom="0">
<s:fill>
<s:SolidColor color="0xC0C0C0" />
</s:fill>
</s:Rect>
<!-- layer 3: text -->
<!--- @copy spark.components.Panel#titleDisplay -->
<s:Label id="titleDisplay" maxDisplayedLines="1"
left="9" right="3" top="1" bottom="0" minHeight="20"
verticalAlign="middle" textAlign="start" fontWeight="bold">
</s:Label>
</s:Group>
<!--
Note: setting the minimum size to 0 here so that changes to the host component's
size will not be thwarted by this skin part's minimum size. This is a compromise,
more about it here: http://bugs.adobe.com/jira/browse/SDK-21143
-->
<s:Group id="topHeaderGroup" minWidth="0" minHeight="0"
includeIn="normalWithHeaderBar, disabledWithHeaderBar, disabledWithHeaderBarWithControlBar, normalWithHeaderBarWithControlBar">
<s:Group left="0" right="0" top="0" bottom="0" mask="topGroupMask">
<s:Rect left="0" right="0" top="0" bottom="0">
<s:stroke>
<s:LinearGradientStroke rotation="90" weight="1">
<s:GradientEntry color="0xE5E5E5" />
<s:GradientEntry color="0xD8D8D8" />
</s:LinearGradientStroke>
</s:stroke>
</s:Rect>
<s:Rect left="1" right="1" top="0" bottom="1">
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0xDADADA" />
<s:GradientEntry color="0xC5C5C5" />
</s:LinearGradient>
</s:fill>
</s:Rect>
</s:Group>
<!-- layer 0: header control bar -->
<!--- @copy spark.components.Panel#headerBarGroup -->
<s:Group id="headerBarGroup" left="0" right="0" top="1" bottom="1" minWidth="0" minHeight="0">
<s:layout>
<s:HorizontalLayout paddingLeft="5" paddingRight="5" paddingTop="3" paddingBottom="3" gap="5" />
</s:layout>
</s:Group>
</s:Group>
<!--- @copy spark.components.SkinnableContainer#contentGroup -->
<s:Group id="contentGroup" minWidth="0" minHeight="0">
</s:Group>
<!--- @private -->
<s:Group id="bottomGroup" minWidth="0" minHeight="0"
includeIn="normalWithControlBar, disabledWithControlBar , disabledWithHeaderBarWithControlBar, normalWithHeaderBarWithControlBar" >
<s:Group left="0" right="0" top="0" bottom="0" mask="bottomGroupMask">
<!-- layer 0: control bar divider line -->
<s:Rect left="0" right="0" top="0" alpha="0.22">
<s:fill>
<s:SolidColor color="0x000000" />
</s:fill>
</s:Rect>
<!-- layer 1: control bar highlight -->
<s:Rect left="0" right="0" top="1" bottom="0">
<s:stroke>
<s:LinearGradientStroke rotation="90" weight="1">
<s:GradientEntry color="0xE5E5E5" />
<s:GradientEntry color="0xD8D8D8" />
</s:LinearGradientStroke>
</s:stroke>
</s:Rect>
<!-- layer 2: control bar fill -->
<s:Rect left="1" right="1" top="2" bottom="1">
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="0xDADADA" />
<s:GradientEntry color="0xC5C5C5" />
</s:LinearGradient>
</s:fill>
</s:Rect>
</s:Group>
<!-- layer 3: control bar -->
<!--- @copy spark.components.Panel#controlBarGroup -->
<s:Group id="controlBarGroup" left="0" right="0" top="1" bottom="1" minWidth="0" minHeight="0">
<s:layout>
<s:HorizontalLayout paddingLeft="5" paddingRight="5" paddingTop="3" paddingBottom="3" gap="10" />
</s:layout>
</s:Group>
</s:Group>
</s:Group>
</s:Group>
</s:SparkSkin>
应用:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
xmlns:panelWithHeader="components.panelWithHeader.*">
<fx:Script>
<![CDATA[
import components.panelWithHeader.skin.PanelWithHeaderBarSkin;
import mx.controls.Alert;
protected function btnRabbit_clickHandler(event:MouseEvent):void
Alert.show("You clicked Header bar button");
protected function btnCat_clickHandler(event:MouseEvent):void
Alert.show("You clicked Control bar button");
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:HGroup verticalCenter="0" horizontalCenter="0">
<s:Panel >
</s:Panel>
<panelWithHeader:PanelWithHeaderBar skinClass="components.panelWithHeader.skin.PanelWithHeaderBarSkin"
title="Panel with header and control bar">
<panelWithHeader:headerBarContent >
<s:Button label="RABBIT" id="btnRabbit" click="btnRabbit_clickHandler(event)"/>
<s:DropDownList>
<s:dataProvider>
<s:ArrayList source="[One,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten]" />
</s:dataProvider>
</s:DropDownList>
</panelWithHeader:headerBarContent>
<panelWithHeader:controlBarContent >
<s:Button label="CAT" id="btnCat" click="btnCat_clickHandler(event)"/>
</panelWithHeader:controlBarContent>
</panelWithHeader:PanelWithHeaderBar>
<panelWithHeader:PanelWithHeaderBar skinClass="components.panelWithHeader.skin.PanelWithHeaderBarSkin"
title="Panel with TabBar and ButtonBar">
<panelWithHeader:headerBarContent >
<s:VGroup gap="3" >
<s:TabBar dataProvider="myViewStack">
<!--<mx:ArrayCollection>
<fx:String>Flash</fx:String>
<fx:String>Director</fx:String>
<fx:String>Dreamweaver</fx:String>
<fx:String>ColdFusion</fx:String>
</mx:ArrayCollection>-->
</s:TabBar>
<s:ButtonBar dataProvider="myViewStack02">
<!--<mx:ArrayCollection>
<fx:String>Flash</fx:String>
<fx:String>Director</fx:String>
<fx:String>Dreamweaver</fx:String>
<fx:String>ColdFusion</fx:String>
</mx:ArrayCollection>-->
</s:ButtonBar>
</s:VGroup>
</panelWithHeader:headerBarContent>
<s:VGroup >
<mx:ViewStack id="myViewStack" borderStyle="solid" >
<s:NavigatorContent id="search" label="Search">
<s:Label text="Search Screen"/>
</s:NavigatorContent>
<s:NavigatorContent id="custInfo" label="Customer Info">
<s:Label text="Customer Info"/>
</s:NavigatorContent>
<s:NavigatorContent id="accountInfo" label="Account Info">
<s:layout>
<s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/>
</s:layout>
<s:Label text="Account Info"/>
</s:NavigatorContent>
</mx:ViewStack>
<mx:ViewStack id="myViewStack02" borderStyle="solid" >
<s:NavigatorContent id="search02" label="Search 02">
<s:Label text="Search Screen 02"/>
</s:NavigatorContent>
<s:NavigatorContent id="custInfo02" label="Customer Info 02">
<s:layout>
<s:VerticalLayout horizontalAlign="center" verticalAlign="middle"/>
</s:layout>
<s:Label text="Customer Info 02"/>
</s:NavigatorContent>
<s:NavigatorContent id="accountInfo02" label="Account Info 02">
<s:Label text="Account Info 02"/>
</s:NavigatorContent>
</mx:ViewStack>
</s:VGroup>
</panelWithHeader:PanelWithHeaderBar>
</s:HGroup>
</s:Application>
【讨论】:
以上是关于如何将控制栏添加到标题栏正下方的 Flex Spark 面板组件的主要内容,如果未能解决你的问题,请参考以下文章
iOS - 通过动画将搜索栏从中心移动到导航栏下方(Swift)
使用 NSLayoutConstraints 添加第二个子视图控制器,始终将其放置在导航栏下方,而不是导航栏之后
将 UINavigationController 添加到 UITabBarController 而不在所有视图中显示标签栏