2 November 2009
ページ ツール |
ActionScript、Flex3、および基本的な2Dグラフィックスに関する知識があれば、この記事の内容を理解するために役立ちます。
中級
Flex 4ベータ版には、スクロール可能なすべてのコンポーネントが実装する必要があるIViewportというインターフェイスがあります。また、Scrollerというコンポーネントを使えば、スクロールバーによるビューポート(IViewportを実装したコンポーネント)のインタラクティブなスクロールを実現できます。このインタラクティブスクロールのサポートは、すべてのグラフィカルユーザーインターフェイス(GUI)ツールキットの基本機能です。Flex 4ベータ版の手法は、Flex 3で用いられているものよりも効率的になっています。詳しくは、MXのスクロールとの比較の項目を参照してください。
ListやTextAreaなど、多くのFlexコンポーネントのスキンには、Scrollerとビューポートが含まれており、デベロッパーは手間をかけずにスクロールを実現できます。この記事では、IViewportインターフェイスの動作の仕組と、Scrollerの簡単な例を紹介します。独自のインタラクティブスクロールコンポーネントを作成したい場合や、Flex 4のスクロールの仕組を詳しく理解したい場合には、以下の内容が参考になります。
GUIでは、ユーザーの画面の領域より大きいドキュメントを表示するために、スクロールを使用します。
Spark(Flex 4ベータ版のコンポーネントとスキンに関する新しいアーキテクチャ)では、IViewportインターフェイスによって、小さい長方形のクリッピングウィンドウをスクロールさせて大きいドキュメントの内容を少しずつ表示する方法が定義されます。ここでいうスクロールとは、小さいクリッピングウィンドウの原点を、大きいドキュメントに対して移動させることを指します。
SparkのScrollerコンポーネントは、ビューポートをインタラクティブにスクロールするための一般的なGUIを提供します。これには垂直と水平の2つのスクロールバーがあり、そのサム位置によってクリッピング長方形のXとYの原点が定義されます。デフォルトでは、スクロールバーは必要な場合だけ表示されます。
図1に、基本的な配置とIViewportのプロパティ(width、height、contentWidth、contentHeight、horizontalScrollPosition、verticalScrollPosition)の関係を示します。
ビューポートのcontentWidthプロパティとcontentHeightプロパティは、ビューポート内に描画されるもの、すなわちビューポートの内容の水平および垂直方向の大きさを示します。ビューポートのwidthプロパティとheightプロパティは、内容の表示されている部分の大きさ、すなわち画面に表示されているものとビューポートのクリッピング長方形の大きさを示します。horizontalScrollPositionプロパティとverticalScrollPositionプロパティは、クリッピング長方形の原点を定義します。アプリケーションは、これらのプロパティを変更することにより、ビューポートをスクロールできます。
SparkのScrollerクラスは、GroupやDataGroupと同様に、1つのビューポートのコンテナです。
Scrollerには垂直と水平のスクロールバーがあり、その値はビューポートのhorizontalScrollPositionおよびverticalScrollPositionプロパティに結び付けられています。スクロールバーのサムのサイズとその値の最大制限値は、contentWidthおよびcontentHeightで指定されるビューポートの内容の相対的な大きさに基づきます。
下のコードはScrollerクラスの単純な例を示します。ScrollerのビューポートはGroupであり、ビューポートの中央に表示されるImageを含みます。
<?xml version="1.0" encoding="utf-8"?>
<s:Application backgroundColor="0x000000"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<s:Scroller left="1" right="1" top="1" bottom="1">
<s:Group>
<mx:Image source="guyrobot.jpg"
horizontalCenter="0"
verticalCenter="0">/
</s:Group>
</s:Scroller>
</s:Application>
アプリケーションの動作バージョンを次に示します。
動作バージョンは、ビューポートの各プロパティの現在値を表示するように変更されています。このバージョンのソースコードはダウンロード可能です。
デフォルトでは、Scrollerは必要なときだけスクロールバーを表示します。すなわち、ビューポートの内容のサイズが実際のサイズよりも大きい場合です。このポリシーは、verticalScrollPolicyおよびhorizontalScrollPolicyプロパティによって変更できます。これらのプロパティのデフォルト値はautoで、必要なときにスクロールバーを表示することを示します。これらのプロパティをonに設定するとスクロールバーが常に表示され、offに設定すると常に非表示になります。
Sparkの基本コンテナクラスはGroupおよびDataGroupと呼ばれ、GroupBaseという共通の基本クラスを持っています。GroupBaseはIViewportを実装しているので、GroupまたはDataGroup内部に作成したものはすべてScrollerに表示できます。Scrollerは自分のビューポートを使用してIViewportを実装できるからです。
IViewportインターフェイスのほとんどの部分は、ここまでの説明に基づいて理解できるはずです。
public interface IViewport extends IVisualElement {
function get width():Number;
function get height():Number;
function get contentWidth():Number;
function get contentHeight():Number;
function get horizontalScrollPosition():Number;
function set horizontalScrollPosition(value:Number):void;
function get verticalScrollPosition():Number;
function set verticalScrollPosition(value:Number):void;
function getHorizontalScrollPositionDelta(scrollUnit:uint):Number;
function getVerticalScrollPositionDelta(scrollUnit:uint):Number;
function get clipAndEnableScrolling():Boolean;
function set clipAndEnableScrolling(value:Boolean):void;
}
ビューポートのwidthとheightは実際の幅と高さを示し、contentWidthとcontentHeightはその内容のXとYの最大の大きさを示します。例えば、ビューポートに長方形(spark.primitives.Rectオブジェクト)が含まれ、その原点が10,20で、幅と高さが100に設定されている場合、ビューポートのcontentWidthは110、contentHeightは120になります。上の例では、画像の原点は0,0(デフォルト)なので、GroupのcontentWidthおよびcontentHeightは、画像の幅と高さにそれぞれ一致します。
BooleanのclipAndEnableScrollingプロパティは、スクロールのサポートのオン/オフを切り替えます。これがfalseの場合、ビューポートは内容をクリッピングせず、スクロール位置はスクロールを制御しません。GroupBaseクラスはデフォルトではclipAndEnableScrollingをfalseに定義しているので、カスタムスクロールコンテナを作成する場合は、このプロパティを明示的にtrueに設定する必要があります。Scrollerは、自分のビューポートをcllipAndEnableScrolling=trueに自動的に設定します。スクロールがデフォルトでオフになっているのは、オンにするとビューポートの表示部分に対してメモリが割り当てられることと、ビューポートの境界内に収まるはずのテキストやグラフィックスが、数値計算とアンチエリアジングのためにわずかに外部にはみ出ることがあるのが理由です。
IViewportインターフェイスのgetHorizontalScrollPositionDeltaおよびgetVerticalScrollPositionDeltaメソッドは、行またはページ単位でスクロールするために必要な距離を計算します。これらのメソッドは、ユーザーがScrollerのスクロールバートラックまたは上下ボタンをクリックするか、マウスホイールを回すか、キーボードのPageUp、PageDown、矢印キーを押したときにスクロールする距離を計算するために用いられます。
SparkのビューポートおよびスクロールAPIは、MXで提供されているものと似ています。基本コンテナクラス(MXのContainer、SparkのGroupとDataGroup)はスクロール機能を備えています。MXでは、Sparkと異なり、すべてのコンテナでスクロールがデフォルトでオンになっており、特別なスクロールコンテナを使用しなくてもスクロールバーを追加できます。MXでは、コンテナの内容が境界を超える場合、コンテナのscrollPolicyプロパティに応じてスクロールバーが表示されます。
Sparkでの変更は、典型的なアプリケーションのサイズと複雑さを減らすことを目的としています。ほとんどのアプリケーションのほとんどのコンテナはスクロールバーやスクロール機能を必要としないので、すべてのコンテナがスクロール機能を備えているMXでは、複雑さとメモリ消費量に関するコストがかかります。Flex 4ベータ版のポリシーは、従量課金とも呼ばれます。これは、アプリケーションのメモリ消費量とパフォーマンスが、必要なSDK機能だけを反映することを意味します。
IViewportインターフェイスとScrollerクラスの使用と拡張については、このほかにも説明すべきことがたくさんあります。このテーマについての記事は、私のブログにときどき投稿されます。Sparkの主要なレイアウト規則、シンタックス、使用例について詳しくは、オンラインドキュメントをまず参照してください。
ビューポートおよびスクロールAPIについて詳しくは、Flex 4 beta Language Referenceで、IViewport、Scroller、GroupBase、Group、DataGroup、およびその他のクラスについて調べてみてください。また、Evtim Georgievのブログでは、レイアウトや仮想化といった関係の深いテーマが扱われています。
また、ビデオも用意されています。Flexに興味があり、簡潔で控えめな技術解説がお好きな方なら、9分間のADC Presents: Scrolling in Gumboが気にいると思います。これは多少古いものですが、扱っている範囲はこの記事よりもやや広くなっています。