【问题标题】:Flex 4 Skin: Change skin based on parent containers stateFlex 4 Skin:根据父容器状态更改皮肤
【发布时间】:2011-03-30 04:57:36
【问题描述】:

我有一个自定义组件 ExpandCollapseMenu,它扩展了 SkinnableContainer。该组件的状态可以是“正常”或“扩展”。
在这个组件内部,我有按钮,根据 ExpandCollapseMenu 的状态具有不同的外观。
这在 ExpandCollapsMenu 的皮肤类中定义按钮时效果很好:

<s:Group id="contentGroup" top="20" left="10" right="10" bottom="10">
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>

    <component:ExpandCollapseMenuButton label="Foo" skinClass.expanded="component.ExpandCollapseMenuButtonExpandedSkin" skinClass.normal="component.ExpandCollapseMenuButtonSkin"  />

</s:Group>

但我不想在 ExpandCollapsMenu 的外观类中定义按钮,我想在使用 ExpandCollapseMenu 的地方定义它们。像这样:

<component:ExpandCollapseMenu skinClass="component.ExpandCollapseMenuSkin">
    <component:ExpandCollapseMenuButton label="Foo"  />
</component:ExpandCollapseMenu>

在这个级别,我无法引用 skinclass.expanded,但我通过使用这样的 CSS 让它工作:

component|ExpandCollapseMenu:expanded component|ExpandCollapseMenuButton {
    skinClass: ClassReference("component.ExpandCollapseMenuButtonExpandedSkin");
}
component|ExpandCollapseMenu:normal component|ExpandCollapseMenuButton { 
    skinClass: ClassReference("component.ExpandCollapseMenuButtonSkin");
}

这是根据父容器状态更改皮肤的好方法吗?还是有更好的办法?

【问题讨论】:

  • 我能问一下你想做什么吗?您的方法非常不标准,我认为可能有更好的方法。
  • 创建一个垂直菜单面板,带有按钮、切换按钮等。所有菜单元素都有窄和宽状态。鼠标悬停菜单面板 = 显示所有按钮的宽版,鼠标悬停 = 显示窄版。
  • 窄版与宽版有何不同?还有,换状态的时候,为什么要换皮肤?!你知道 Flex 皮肤也可以有状态吗?它们基于组件状态(可以被覆盖/修改)。我建议您阅读皮肤状态,而是让孩子检查他们的大小以在宽和窄之间改变状态,因为父母不需要“告诉”他们。
  • 我改变了皮肤,因为按钮本身已经有 4 个状态。它的灵感来自googolflex.com/?p=352。因为你不能有多个状态,所以替代方法是拥有所有排列(8 个状态),这是一个 hack IMO。孩子们根据标准 CSS 选择皮肤,他们的父母没有告诉他们(至少在最后一个版本中,你可能在我描述的第一个版本中是对的)。 ExpandCollapseMenu 根据孩子获得它的大小,所以我看不出孩子们如何检查他们的大小来决定他们的状态?
  • 另请注意,所有按钮同时显示其宽版本,而不仅仅是您正在与之交互的那个。

标签: apache-flex flex4


【解决方案1】:

我建议您在 ExpandCollapseMenu 容器级别解决问题。当 ExpandCollapseMenu 的状态发生变化时,您应该遍历子项并为每个子项设置一些标志。

所以我建议为 ExpandCollapseMenuButton 引入扩展:Boolean 标志。

如果 ExpandCollapseMenu 可以包含其他实例的类型,则会出现此问题。在这种情况下,我们可以通过以下两种方式解决:

  1. 检查迭代过程中的组件是否为 ExpandCollapseMenuButton 实例(使用 is 运算符)。
  2. 引入如下简单的可扩展界面:

    public interface Expandable
    {
       function set expanded(value:Boolean);
    }
    

并通过 ExpandCollapseMenuButton 实现此接口。所以你可以在没有 ExpandCollapseMenuButton 依赖的情况下更灵活地在迭代器主体中使用 is 运算符。

所以拼图的最后一部分是在 ExpandCollapseMenuButton 类中实现 setter 并切换皮肤:

private var expandedDirty:Boolean;
private var _expanded:Boolean;
public function set expanded(value:Boolean)
{
   if (value == _expanded)
      return;
   _expanded = value;
   expandedDirty = true;
   invalidateProperties();
}

override protected function commitProperties():void
{
   super.commitProperties();
   if (expandedDirty)
   {
      if (_expanded)
         setStyle("skinClass", ExpandCollapseMenuButtonExpandedSkin);
      else
         setStyle("skinClass", ExpandCollapseMenuButtonSkin);
      expandedDirty = false;
   }
}

【讨论】:

  • 感谢康斯坦丁。是的,除了 ExpandCollapseMenuButtons 之外,还有其他实例,例如切换按钮、按钮组、滑块等。但是正如您所说,这可以通过某种通用方式解决,例如界面。
猜你喜欢
  • 2011-08-09
  • 2011-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-24
  • 1970-01-01
  • 1970-01-01
  • 2014-08-23
相关资源
最近更新 更多