モバイルアプリケーションでのビューの定義

通常、モバイルアプリケーションでは複数の画面またはビューを定義します。ユーザーがアプリケーションをナビゲートするのに応じて、様々なビューに切り替わります。

ナビゲーションは、アプリケーションのユーザーにわかりやすいものにします。つまり、ユーザーが 1 つのビューから別のビューに移動する際には、前のビューに戻れるようにする必要があります。「ホーム」ボタンや、他の最上位のナビゲーション補助(ユーザーが他の場所からアプリケーションの場所に移動できる機能)を定義できます。

モバイルアプリケーションのビューを定義するには、View コンテナを使用します。モバイルアプリケーションのビュー間のナビゲーションを制御するには、ViewNavigator コンテナを使用します。

以下をお勧めします。

Create a mobile application with multiple views

Peter Elst
複数のビューを使用するデータ駆動型の Flex モバイルアプリケーションの作成方法が説明されています

共有したいチュートリアルはありますか?

以下をお勧めします。

共有したいチュートリアルはありますか?

Handling data while switching between views

Holly Schinsky
モバイルアプリケーションでのビュー間のナビゲート時のデータの処理方法が説明されています

Adobe Flex Mobile applications – passing data between views

Peter Witham
ビュー間でデータを簡単にすばやく受け渡しできることを説明するビデオです。

pushView() を使用したビューの変更

新規のビューをスタックにプッシュするには、ViewNavigator.pushView() メソッドを使用します。ViewNavigator には、ViewNavigatorApplication.navigator プロパティを使用してアクセスします。ビューをプッシュすると、アプリケーションの表示が新しいビューに切り替わります。

pushView() メソッドの構文は、次のとおりです。

pushView(viewClass:Class, 
    data:Object = null, 
    context:Object = null, 
    transition:spark.transitions:ViewTransitionBase = null):void
ここで、各項目の説明は次のとおりです。
  • viewClass には、ビューのクラス名を指定します。通常、このクラスはビューを定義する MXML ファイルに相当します。

  • data には、ビューに渡すデータを指定します。このオブジェクトは、新しいビューの View.data プロパティに書き込まれます。

  • context には、ViewNavigator.context プロパティに書き込む任意のオブジェクトを指定します。新規のビューを作成すると、このプロパティが参照され、この値に基づいてアクションが実行されます。例えば、context の値に基づいて、様々な方法でデータが表示されます。

  • transition には、ビューが新規のビューに切り替わる際に再生するトランジションを指定します。ビューのトランジションについて詳しくは、モバイルアプリケーションでのトランジションの定義を参照してください。

単一の Object を渡すための data 引数の使用

新規のビューに必要なデータを格納した単一の Object を渡すには、data 引数を使用します。その後、次の例に示すように、View.data プロパティを使用して、オブジェクトにアクセスできます。

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\mobile\views\EmployeeView.mxml -->
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    title="Employee View">
    <s:layout>
        <s:VerticalLayout paddingTop="10"/>
    </s:layout>
    
    <s:VGroup>
        <s:Label text="{data.firstName}"/>
        <s:Label text="{data.lastName}"/>
        <s:Label text="{data.companyID}"/>
    </s:VGroup>
</s:View>

この例では、EmployeeView は EmployeeView.mxml ファイルに定義されています。このビューは、data プロパティを使用して、渡された Object から従業員の姓名および従業員の ID にアクセスします。

View.data プロパティは、View オブジェクトに対する add イベント時点までには確実に有効になります。View コンテナのライフサイクルについて詳しくは、Spark の ViewNavigator コンテナと View コンテナのライフサイクルを参照してください。

アプリケーションの最初のビューに対するデータの引き渡し

ViewNavigatorApplication.firstView プロパティと ViewNavigator.firstView プロパティでは、アプリケーションの最初のビューを定義します。最初のビューにデータを渡すには、ViewNavigatorApplication.firstViewData プロパティまたは ViewNavigator.firstViewData プロパティを使用します。

ビューに対するデータの引き渡し

次の例では、ViewNavigatorApplication コンテナを使用して、モバイルアプリケーションを定義します。ViewNavigatorApplication コンテナは、アプリケーションによって定義された各ビューのナビゲートに使用する ViewNavigator クラスの単一のインスタンスを自動的に作成します。

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\mobile\SparkSingleSection.mxml -->
<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
        firstView="views.EmployeeMainView">
 
    <fx:Script>
        <![CDATA[
            protected function button1_clickHandler(event:MouseEvent):void {
                // Switch to the first view in the section.
                navigator.popToFirstView();
            }
        ]]>
    </fx:Script>
 
    <s:navigationContent>
        <s:Button icon="@Embed(source='assets/Home.png')" 
            click="button1_clickHandler(event)"/>
    </s:navigationContent>
</s:ViewNavigatorApplication>

この例では、ActionBar コントロールのナビゲーション領域に「ホーム」ボタンを定義します。「ホーム」ボタンを選択すると、スタックからすべてのビューがポップされて最初のビューに戻ります。次の図は、このアプリケーションを示しています。

次の例に示すように、EmployeeMainView.mxml ファイルでは、アプリケーションの最初のビューを定義します。

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\mobile\views\EmployeeMainView.mxml -->
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    title="Employees">
    <s:layout>
        <s:VerticalLayout paddingTop="10"/>
    </s:layout>
        
    <fx:Script>
        <![CDATA[
            import spark.events.IndexChangeEvent;

            protected function myList_changeHandler(event:IndexChangeEvent):void {
                navigator.pushView(views.EmployeeView,myList.selectedItem);
            }

        ]]>
    </fx:Script>
    
    <s:Label text="Select an employee name"/>
    <s:List id="myList"
        width="100%" height="100%"
        labelField="firstName"
        change="myList_changeHandler(event)">
        <s:ArrayCollection>
            <fx:Object firstName="Bill" lastName="Smith" companyID="11233"/>
            <fx:Object firstName="Dave" lastName="Jones" companyID="13455"/>
            <fx:Object firstName="Mary" lastName="Davis" companyID="11543"/>
            <fx:Object firstName="Debbie" lastName="Cooper" companyID="14266"/>
        </s:ArrayCollection>
    </s:List>
</s:View>

このビューには、ユーザーが従業員名を選択できる List コントロールを定義します。名前を選択すると、change イベントのイベントハンドラーによって、別のビューのインスタンスが EmployeeView というスタックにプッシュされます。EmployeeView のインスタンスがプッシュされると、アプリケーションでは EmployeeView ビューへの切り替えが処理されます。

この例の pushView() メソッドでは、新しいビューおよび新しいビューに渡すデータを定義する Object の 2 つの引数が使用されます。この例では、List コントロールで現在選択されているアイテムに対応するデータオブジェクトを渡します。

次の例は、EmployeeView の定義を示しています。

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\mobile\views\EmployeeView.mxml -->
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    title="Employee View">
    <s:layout>
        <s:VerticalLayout paddingTop="10"/>
    </s:layout>
    
    <s:VGroup>
        <s:Label text="{data.firstName}"/>
        <s:Label text="{data.lastName}"/>
        <s:Label text="{data.companyID}"/>
    </s:VGroup>
</s:View>

EmployeeView には、List コントロールのデータプロバイダーからの 3 つのフィールドが表示されます。EmployeeView は、View.data プロパティを使用して、渡されたデータにアクセスします。

ビューからのデータの受け取り

ViewNavigator.popView() メソッドは、現在のビューからスタックにある前のビューに制御を戻します。popView() メソッドを実行すると、現在のビューが破棄され、スタックにある前のビューが復元されます。前の View の復元には、その data プロパティをスタックからリセットすることも含まれます。

作成時に送出されるイベントなど、ビューのライフサイクルについて詳しくは、Spark の ViewNavigator コンテナと View コンテナのライフサイクルを参照してください。

新しいビューは、非アクティブ化された時点の元の data オブジェクトが設定されて復元されます。 したがって、通常は元の data オブジェクトを使用して古いビューから新しいビューにデータを渡すことはしません。 代わりに、古いビューの createReturnObject() メソッドをオーバーライドします。createReturnObject() メソッドは、単一の Object を返します。

返されるオブジェクトの種類

createReturnObject() メソッドによって返される Object は、ViewNavigator.poppedViewReturnedObject プロパティに書き込まれます。poppedViewReturnedObject プロパティのデータのタイプは ViewReturnObject です。

ViewReturnObject には、contextobject の 2 つのプロパティを定義します。object プロパティには、createReturnObject() メソッドによって返される Object が格納されます。context プロパティには、pushView() を使用してナビゲーションスタックにビューがプッシュされたときにビューに渡された context 引数の値が格納されています。

poppedViewReturnedObject プロパティは、add イベントがビューで受信されるまでに、新しいビューに確実に設定されます。poppedViewReturnedObject.object プロパティが null の場合、データは返されません。

例:ビューに対するデータの引き渡し

次の SelectFont.mxml の例は、フォントサイズを設定できるビューを示しています。createReturnObject() メソッドのオーバーライドにより、値は Number として返されます。前のビューから渡された data プロパティの fontSize フィールドによって、TextInput コントロールの初期値が設定されます。

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\mobile\views\SelectFont.mxml -->
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    title="Select Font Size"
    add="addHandler(event);">
    <s:layout>
        <s:VerticalLayout paddingTop="10"
            paddingLeft="10" paddingRight="10"/>
    </s:layout>
    
    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;

            // Define return Number object.
            protected var fontSize:Number;
            
            // Initialize the return object with the passed in font size. 
            // If you do not set a value, 
            // return this value for the font size. 
            protected function addHandler(event:FlexEvent):void {
                fontSize = data.fontSize;
            }
            
            // Save the value of the specified font.
            protected function changeHandler(event:Event):void {
                fontSize=Number(ns.text);
                navigator.popView();
            }
            
            // Override createReturnObject() to return the new font size.
            override public function createReturnObject():Object {
                return fontSize;
            }
        ]]>
    </fx:Script>
        
    <s:Label text="Select Font Size"/>
    <!-- Set the initlial value of the TextInput to the passed fontSize -->
    <s:TextInput id="ns" 
        text="{data.fontSize}"/>
    <s:Button label="Save" click="changeHandler(event);"/> 
</s:View>

次の図は、SelectFont.mxml によって定義されるビューを示しています。

次の例の MainFontView.mxml というビューでは、SetFont.mxml で定義されているビューを使用しています。 MainFontView.mxml ビューでは、次のことが定義されています。
  • SetFont.mxml で定義されているビューに切り替える ActionBar の Button コントロール。

  • View.data プロパティが null かどうかを最初に判断する add イベントのイベントハンドラー。null の場合は、イベントハンドラーが data.fontSize フィールドを View.data プロパティに追加します。

    data プロパティが null でない場合は、イベントハンドラーがフォントサイズを data.fontSize フィールドの値に設定します。

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\mobile\views\MainFontView.mxml -->
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    title="Font Size"
    add="addHandler(event);">
    <s:layout>
        <s:VerticalLayout paddingTop="10"/>
    </s:layout>
    
    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;
            
            // Change to the SelectFont view, and pass the current data property.
            // The data property contains the fontSize field with the current font size.
            protected function clickHandler(event:MouseEvent):void {
                navigator.pushView(views.SelectFont, data);
            }

            // Set the font size in the event handler for the add event.
            protected function addHandler(event:FlexEvent):void {
                // If the data property is null, 
                // initialize it and create the data.fontSize field.
                if (data == null) {
                   data = new Object(); 
                   data.fontSize = getStyle('fontSize');
                   return;
                }
                
                // Otherwise, set data.fontSize to the retured value,
                // and set the font size. 
                data.fontSize = navigator.poppedViewReturnedObject.object;
                setStyle('fontSize', data.fontSize);
            }
        ]]>
    </fx:Script>
    
    <s:actionContent>
        <s:Button label="Set Font&gt;"
            click="clickHandler(event);"/>
    </s:actionContent>
       
    <s:Label text="Text to size."/>
</s:View>

縦方向と横方向のアプリケーションの設定

デバイスの方向が変わると、モバイルデバイスによって、アプリケーションの方向が自動的に設定されます。異なる方向にアプリケーションを設定するために、Flex では、縦方向と横方向に対応する portraitlandscape の 2 つのビューステートを定義します。これらのビューステートを使用して、方向に基づいたアプリケーションの特性を設定します。

次の例では、ビューステートを使用して、現在の方向に基づいて Group コンテナの layout プロパティを制御します。

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\mobile\views\SearchViewStates.mxml -->
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    title="Search">
    <s:layout>
        <s:VerticalLayout paddingTop="10"/>
    </s:layout>
    
    <s:states>
        <s:State name="portrait"/>
        <s:State name="landscape"/>
    </s:states>
        
    <s:Group>
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
        <s:layout.landscape>
            <s:HorizontalLayout/>
        </s:layout.landscape>
        <s:TextInput text="Enter search text" textAlpha="0.5"/>
        <s:Button label="Search"/>
    </s:Group>
    <s:TextArea text="search results" textAlpha="0.5"/>
</s:View>

この例は、検索ビューを定義しています。Group コンテナは、入力検索テキストと「検索」ボタンのレイアウトを制御します。縦方向モードの場合、Group コンテナでは垂直方向のレイアウトが使用されます。レイアウトを横方向モードに変更すると、Group コンテナで水平方向のレイアウトが使用されるようになります。

レイアウトモードをサポートするためのカスタムスキンの定義

モバイルアプリケーションには、カスタムスキンクラスを定義できます。縦方向および横方向のレイアウトがサポートされるスキンでは、portraitlandscape のビューステートを処理する必要があります。

ユーザーがデバイスを回転したときにレイアウトの方向が変更されないようにアプリケーションを設定できます。そのためには、アプリケーションの -app.xml で終わる XML ファイルを編集し、次のプロパティを設定します。

  • レイアウトの方向がアプリケーションによって変更されないようにするには、<autoOrients> プロパティを false に設定します。

  • 方向を設定するには、<aspectRatio> プロパティを portrait または landscape に設定します。

Spark の ViewNavigator コンテナのオーバーレイモードの設定

デフォルトでは、モバイルアプリケーションのタブバーと ActionBar コントロールによって、アプリケーションのビューでは使用できない領域が定義されます。つまり、コンテンツには、モバイルデバイスのフルスクリーンサイズを使用できません。

ただし、これらのコンポーネントのデフォルトのレイアウトは、ViewNavigator.overlayControls プロパティを使用して変更できます。overlayControls プロパティを true に設定すると、アプリケーションのコンテンツ領域は、スクリーンの幅と高さ全体に広がります。ActionBar コントロールとタブバーは、部分的に透明になるアルファ値を使用してコンテンツ領域に重ねられます。

ViewNavigator コンテナの spark.skins.mobile.ViewNavigatorSkin というスキンクラスでは、異なる値の overlayControls プロパティを処理するためのビューステートを定義します。overlayControls プロパティが true の場合は、現在のステート名に「AndOverlay」が追加されます。例えば、ViewNavigator のスキンは、デフォルトで「portrait」ステートになります。overlayControls プロパティが true の場合は、ナビゲーターのスキンステートが「portraitAndOverlay」に変更されます。

Spark の ViewNavigator コンテナと View コンテナのライフサイクル

ユーザーがモバイルアプリケーションでビューを別のビューに切り替えると、Flex により一連の操作が実行されます。ビューの切り替えプロセスの様々な段階で、Flex によってイベントが送出されます。これらのイベントを監視して、プロセスの途中でアクションを実行できます。例えば、removing イベントを使用して、あるビューから別のビューへの切り替えをキャンセルできます。

次の図は、View A という現在のビューから View B という別のビューに切り替えるプロセスを示しています。