为了保障原创作者在本站发表文章的利益, 并维护本站原创的精神, 特声明: RIAShanghai对有以下任何情况之一的文章将不通知作者并直接进行快意删除:
- 非原创, 或者原创但一文多发;
- 各种形式的广告与吹擂;
- 不符合本站文章格式.
欢迎各位读者监督. 谢谢合作. 另: 作为Adobe正式的UG, 我们将把Adobe不定期分发的软件,书籍及各种纪念品赠送给发文活跃的作者, 共同进步.
In large "enterprise" systems, there are thousands of UI components displaying different information. Opening multiple windows for containing these components is not practical. Often, you need to reuse the same space to display different UI components. In order to create an appealing UI experience, you'd like display some effects when replacing UI components in a container. You could wire the effects inline with your UI code all together, e.g,:
// replace A with B in container C
var _sequence:Sequence;
var _dissolve = new Dissolve();
_dissolve.alphaFrom = 1;
_dissolve.alphaTo = 0;
_sequence.addChild(_dissolve);
_removeAction = new SimpleRemoveAction();
_sequence.addChild(_removeAction);
_addAction = new SimpleAddAction();
_sequence.addChild(_addAction);
...
_sequence.play();
// replace E with F in container G
_sequence = new Sequence();
...
but soon you'll have long, repetitive (in certain extent) code that hard to manage.
Applying the strategy pattern
The strategy pattern is often used for dynamically configuring the algorithm for certain tasks. Here our task is to replace UI components while playing some effects. The difference between algorithms are on the effects.
First, we create an interface representing the replace algorithm:
package
{
import mx.core.Container;
import mx.core.UIComponent;
import mx.effects.CompositeEffect;
import mx.effects.Effect;
/**
* The strategy used for replacing UI components while playing effects.
*/
public interface IReplaceEffectStrategy {
/**
* Replaces the UI component in the given container while playing the effect.
* @param container the target container
* @param uiToBeRemoved the component to be added or null if remove only
* @param uiToBeAdded the component to be removed or null if add only
* @param addIndex the index that the new child should be added to or -1 if adding to the last.
* @return the effect object, you can use this object to monitor effect starting and ending.
*/
function replaceWithEffects(container:Container, uiToBeRemoved:UIComponent, uiToBeAdded:UIComponent, addIndex:int = -1):CompositeEffect;
/**
* A shortcut function equivalent to replaceWithEffects(container, null, uiToBeAdded, addIndex).
*/
function addWithEffects(container:Container, uiToBeAdded:UIComponent, addIndex:int = -1):CompositeEffect;
/**
* A shortcut function equivalent to replaceWithEffects(container:Container, uiToBeRemoved, null).
*/
function removeWithEffects(container:Container, uiToBeRemoved:UIComponent):CompositeEffect;
} // end class
} // end package
Then you create different algorithms by implementing the interface:
public class CoolReplaceEffectStrategy implements IReplaceEffectStrategy ...
public class SuperReplaceEffectStrategy implements IReplaceEffectStrategy ...
With multiple implementations, you can create a factory for easy look up of the strategies.
The revised code
Whenever you need to replace UI components, you simply need an instance of IReplaceEffectStrategy:
private var replaceEffectStrategy:IReplaceEffectStrategy = new CoolRotateReplaceEffect();
replaceEffectStrategy.replaceWithEffects(container, __existingContent, ui);
Note: Not only the code is cleaned up, the same strategy object can be reused. Further more, it's very easy to switch the replace effect strategy.