Flex の最も強力な特徴の 1 つは、Flex を使うことで非常に柔軟に設計を行えることです。この柔軟性は主に、Adobe が Flex に CSS を実装していることによるものです。例えば私は最近、新しい Adobe AIR™ アプリケーションのシニア UI 開発者として働く中で、全世界の 16 万人の人達に最初の公開リリースを正式に提供する数日前に、デザインに関する変更要求を何件も受け取りました。こうしたリリース直前での変更要求を残虐な行為と見なす開発者が多いと思いますが、私は 20 分間もかからずに変更を完了し、その変更をバージョン管理ツールにチェックインすることができました。これは Flex と CSS の強力さのおかげです。
私は Flex の CSS を UI の開発に活用しています。私の経験によれば、UI の開発では必ずある特定の事態が起こるものであり、その事態に備えて準備する必要があります。そうした必然的な事態の 1 つが、たとえ事前にどれほど準備をしても、プロジェクトでのデザインや機能に関する要件が変更されることです。しかも開発ライフサイクル全体をとおして頻繁に変更されます。これはチーム・ベースの環境で大規模なアプリケーションを開発する際にはやむを得ないことであり、この状況に最もうまく対処するには関係するすべての人の動きを予測し、その予測に従って自分自身があらかじめ適切な位置にいるようにします。この開発手法をマスターできると、常に優位な状況を保つことができ、変化するターゲットに対応するのがかなり容易になります。こうした理由から、私にとって Flex での開発は楽しい作業です。Flex には CSS が統合されているため、まさに上記の開発手法を実践できるのです。
この記事の目標は、この記事を読み終わるまでに皆さんが Flex の CSS の強力な機能を活用できるようになり、Flex UI 開発のマスターとして要件が変更されて行く状況にうまく対処できるようになることです。既に Flex を積極的に使用している読者の場合には、Flex で (特にエンタープライズ・レベルのアプリケーションで) CSS を活用するための新しい手法を、この記事から学んで欲しいと思います。
オブジェクト指向のデザイン・パターンでは、ほとんどの場合デザインのロジックを動作機能とは別にします。Adobe ActionScript™ はオブジェクト指向言語であるため、こうしたオブジェクト指向プログラミング (OOP: Object-Oriented Programming) の慣習に従っておくのが賢明です。そうすることによって、柔軟性がもたらされるため、アプリケーションの規模が大きくなっても保守を容易に行えるようになり、コードを再利用することができ、パフォーマンスも改善される、といったメリットが得られます。
Web デザインの世界では、Web サイトのデザインを構成するコードをカプセル化する手段として、CSS を使うのが標準的です。CSS は強力で成熟しているため、経験豊富な大部分の Web デザイナーは Web サイトのデザインやレイアウトのプロパティーの大部分を CSS を最大限に活用して実装しようとします。その結果として、サイトのルック・アンド・フィールを詳細かつ柔軟に制御することができます。CSS は 3、4 年ほど前から一般的に使われるようになりました。その当時 Web 開発者達は、Web サイトのデザインをサイトの動作機能と独立させればデザインを容易に変更することができ、サイトの動作を記述したコードに問題を発生させたり、マイナスの影響を与えたりすることがないと気付き始めたのです。その結果、テンプレートやスキニング、同じコード・ベースの再スキニングなどが盛んに使われるようになりました。例えば、私は自分のブログの Web サイトに WordPress を積極的に使っています。この同じオープンソースのコード・ベースをブログ・サイトに活用している人達は何万人もいますが、それにもかかわらず、WordPress で作成されたことをまったく意識させないサイトに遭遇することがよくあります。これは CSS を使用することでコードとデザインとが驚くほど明確に分離されるおかげなのです。
何よりもまず、Web デザインの経歴を持つ読者の場合には、Flex の CSS が W3C の CSS 仕様と同じ規約には従っていないことを理解することが重要です。W3C の CSS Version 2.0 の仕様では単語の区切りにハイフン (-) が使われていますが、Flex に実装されたコーディング規約ではハイフンを使いません。代わりに Flex の CSS 実装ではラクダ記法を使います。例えば、W3C の CSS2 仕様での vertical-center は、Flex の CSS での verticalCenter と同じです。ラクダ記法を使用する言語で既にプログラミングを行っている人は、非常に容易にこの記法に慣れることができます。幸いなことに、CSS 2.0 仕様に記述されている内容の大半は Flex の CSS 実装にもあります。また、Flex に実装された CSS は W3C 標準の CSS 2.0 を大幅に拡張しており、Flex コンポーネントに特有のスタイル・プロパティーが追加されています。
スタイルを維持する: コンポーネントとスタイル・プロパティー
Flex CSS のスタイルシートを作成する前に、最初にスタイルの実装方法を検討することをお勧めします。ここでは簡単のため、スタイルを宣言する 4 つの基本的な方法を説明します。
- コンポーネントのクラス名を使用する。コンポーネントのクラス名をスタイル名として使うことで、コンポーネントにスタイルを設定することができます。
TitleWindow { borderColor: #f7f7f7; borderAlpha: 1; borderThicknessLeft: 0; borderThicknessTop: 0; borderThicknessBottom: 0; borderThicknessRight: 0; cornerRadius: 0; headerHeight: 0; highlightAlphas: 1, 1; headerColors: #f7f7f7, #f7f7f7; footerColors: #f7f7f7, #f7f7f7; backgroundColor: #f7f7f7; dropShadowEnabled: true; } - 一意のスタイル名を使用する。一意のスタイル名を使ってスタイルを宣言することができます。名前の前にドットを付けること、そしてラクダ記法の規約に従うことを忘れないようにします。
.altText { fontFamily: TVNordEFCEOP-RegularCon; fontSize: 18; color: #FFFFFF; } - コンポーネント名とスタイル名を使用する。同じコンポーネントに対して複数のデザインが必要な場合 (ビュー・ステートが複数あるアプリケーションでは一般的です) には、コンポーネントにスタイル名を設定することもできます。この方法では、指定されたコンポーネントのみに特定のスタイルを割り当てることができます。
Text.bigYellowText { color:#EFB526; fontSize:36; fontWeight:Bold; } - グローバル・セレクターを使用する。グローバル・セレクターは特別な種類のセレクターであり、内部にプロパティーが設定された、アプリケーション内のすべてのコンポーネントに影響します。例えば、
cornerRadiusスタイル・プロパティーを持つすべての表示オブジェクト・コンポーネントに対して、cornerRadiusスタイル・プロパティーを、次のようにして4に設定することができます。global { cornerRadius: 4; }
基本的にグローバル・セレクターによってプロパティーのデフォルト値が設定されますが、この値は容易に変更することができます。例えば、インラインまたは CSS ファイルで Button コンポーネントの cornerRadius プロパティーを 0 に設定した場合、この値は、同じく設定されたグローバルなデフォルトの 4 よりも優先されます。その結果、すべての Button コンポーネントは値が 0 の cornerRadius を含むことになります。さらに、4 というグローバル設定も 0 という Button 設定も、追加のスタイルを作成することで変更することができます。
Button.altCornersButton
{
cornerRadius: 8;
}
|
Flex での CSS の実装方法を選択する際には、状況と環境を考慮する必要があります。デザインを実装する方法を検討する際には、デザインを実装しようとしているアプリケーションを概念的に 5 万フィート上空から眺めることが重要です。以下の方法は Flex で CSS を使う場合の最も一般的な方法です。
Flex の UIComponent 基底クラスを継承する Flex コンポーネントを利用すると、共通のスタイルをインラインで (つまり MXML コンポーネントの宣言タグ内部で) プロパティーとして設定することができます (リスト 1)。表示オブジェクトのレイアウト・プロパティーは、そのオブジェクトに固有であることが多いものです。そのため、あるコンポーネントに対して何らかのプロパティー (x、y、height、width、top、right、left、bottom、horizontalCenter、verticalCenter、horizontalAlign、verticalAlign) が明示的に設定されることがよくあります。
リスト 1. MXML コンポーネントのインスタンスのプロパティーとしてスタイルを設定する
<mx:Button id="volumeIcon" cornerRadius="0" alpha="0.9" verticalCenter="0" enabled="true" toolTip="Volume Control" click="toggleVolumeControl();" /> |
リスト 1 は、volumeIcon という値の id によって Button コンポーネントの特定インスタンスに特有のスタイル・プロパティーを設定する機能の例を示しています。ここでは、こうした特別なスタイル値を要求するボタンがこれだけであることがわかっているため、この特定のボタンの cornerRadius、alpha、verticalCenter を明示的に設定しています。
MXML コンポーネント・タグにスタイル・プロパティーを設定する際の適切なやり方としては、今設定しようとしている特定のプロパティー値が、そのコンポーネントに特有であることがわかっている場合にのみ、上述の方法でプロパティーを設定するように心がけることです。例えば、あるアプリケーションには表示オブジェクトを隙間なく垂直方向に積み上げるためのコンテナーが必要だとします。同時に、そのアプリケーションの他の VBox コンテナーは表示オブジェクト間に間隔を必要とする、ということがわかっているとします。こうした状況では、その VBox コンポーネントのインスタンスに verticalGap プロパティーを明示的に設定する必要があります (リスト 2)。
リスト 2. この VBox コンテナー・コンポーネントのインスタンスで verticalGap を明示的に 0 に設定する
<mx:VBox id="myVBox" verticalGap="0" x="15" y="15" width="100%" height="100%"> (...) </mx:VBox> |
この方法では、<mx:Style/> タグを使ってスタイルまたはアセットを MXML ファイルに直接埋め込みます。実際には、スタイル情報を MXML ファイルに直接埋め込むことが適切なケースは稀です。重要な注意点として、アプリケーションの中に CSS が大量に埋め込まれていると、アプリケーションの規模が大きくなるにつれてデザインの維持が次第に困難になることを認識しておく必要があります。それを念頭に置き、この方法を積極的に使用することは避け、必要な場合にのみ使用するようにします。リスト 3 はスタイル宣言が埋め込まれた例です。この宣言は外部の CSS ファイルの中に記述すべきものであり、そうすればコードの保守性を高めることができます。
リスト 3. MXML アプリケーション・ファイルの中にスタイルを直接埋め込む
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
showFlexChrome="false"
borderStyle="none"
keyUp="{this.onKeyStrokeEvent(event);}">
<mx:Style>
.bGroup {
borderSides:"left,bottom,right";
borderStyle:"solid";
borderColor:#6d6f71;
borderLeftThickness:3;
borderRightThickness:3;
borderBottomThickness:1;
dividerColor:#6d6f71;
dividerThickness:3;
}
</mx:Style>
<mx:Script>
<![CDATA[
(...)
|
ただし、だからといって、この方法を絶対に使ってはいけないというわけではありません。リスト 4 は、あるアプリケーションのために私が作成したコンポーネントをスケール・ダウンしたものですが、これは Flex の AplicationControlBar をベースにしています。提供されたデザインでは、コントロール・バーの各ボタンは実際には 1 つの単語のテキストにすぎず、ボタンと言うよりもむしろリンクに似ていました。また、こうした 1 つの単語から成るすべてのリンクの間は小さなビュレットで区切られていました。私にはアプリケーション全体のデザインが既にわかっていたため、このビュレットによる区切りがアプリケーションのメインのコントロール・バーに特有であり、他にはどこにも現れないことを知っていました。最も重要な点として、このビュレットは同じコンポーネントの中に数回現れるため、MXML ファイル内の独自のプライベート・クラスとしてビュレットの画像を埋め込むことに十分な意味がありました。こうすることで、リンクの間に配置した各画像コントロールから実際のビュレットの画像にバインドすることができたのです。もしこの方法を使わなかったとしたら、同じ画像のインスタンスが複数作成されることになっていたことでしょう。それではシステム・リソースの浪費でしかありません。
リスト 4. 画像を直接埋め込む
<?xml version="1.0" encoding="utf-8"?>
<mx:ApplicationControlBar xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
[Embed(source="assets/bullet_black.png")]
[Bindable]
private var bullet:Class;
]]>
</mx:Script>
<mx:HBox x="10" y="10" id="hbox" horizontalGap="10" width="350">
<mx:LinkButton label="Help" styleName="appBarButton"/>
<mx:Image source="{bullet}" />
<mx:LinkButton label="About" styleName="appBarButton"/>
<mx:Image source="{bullet}" />
<mx:LinkButton label="Minimize" styleName="appBarButton" />
<mx:Image source="{bullet}" />
<mx:LinkButton label="Quit" styleName="appBarButton"/>
</mx:HBox>
</mx:ApplicationControlBar>
|
Flex アプリケーションまたは AIR アプリケーションには、ソース・コード・ディレクトリーのルートに MXML ファイルが 1 つあり、このファイルは Application クラス (Flex) または WindowedApplication クラス (AIR) がベースになっています。これはデフォルトの MXML アプリケーション・ファイルであり、<mx:Application/> または <mx:WindowedApplication/> で始まります。アプリケーションのスタイルシートのソースは、そのアプリケーションの基底クラスの宣言の直後に置く必要があります (リスト 5)。
リスト 5. アプリケーションのメインの MXML ファイル以外のファイルでスタイルシートを宣言するとエラーが発生する
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
showFlexChrome="false"
dropShadowEnabled="false"
borderStyle="none"
applicationComplete="{this.appInit(event);}"
>
<mx:Style source="com/passalong/assets/RED_SKIN_MAIN.css"/>
<mx:Script>
<
Dan Orlando はソフトウェア・アーキテクトであり、Flex、AIR、ActionScript などを含む、クライアントでのリッチ・クライアント・サーバー・アプリケーションを専門としています。彼はさまざまな Web サービス・プロトコルとサーバー・サイド言語を扱っています。彼は Avijax のメーカーである Vision Media Group の共同設立者であり、また (RED)WIRE チームのシニア UI 開発者でもあります。