読者です 読者をやめる 読者になる 読者になる

メイドさんの萌え萌え動画アプリを作ってみたよ

メイドさんの萌え萌え動画アプリを作ってみました。

実際のサンプルはAndroid Marketで「メイド」や「萌」で検索すれば出てくるかと思います。
今回のアプリはシンプルでデーターをネットから取得して新着の動画のリストを表示するだけのものです。
動画の再生部分ですが、以下のようにyoutubeのURLを指定すると、ユーザーは youtube の player を選択することができます。

navigateToURL( new URLRequest( "http://www.youtube.com/watch?v=bJ7TWfq0weE" ) );

できればインテントでyoutubeのプレイヤーを呼び出せるといいのですが、いまいち分かりません。
ソースはこちらになります。

home.mxml

サーバーから新着動画をJSONで取得してリスト状に表示します。

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        title="Maid MoeTube Channel"
        xmlns:mx="library://ns.adobe.com/flex/mx"
        actionBarVisible="false"
        destructionPolicy="none"
        creationComplete="view1_creationCompleteHandler(event)"
        >
    <fx:Style>
        @namespace s "library://ns.adobe.com/flex/spark";
        @namespace mx "library://ns.adobe.com/flex/mx";
        .myMessage{
            color:#ff4ec3;
            border-color:#ffffff;
            font-size:24px;
            font-weight:normal;
        }
    </fx:Style>
    <fx:Script>
        <![CDATA[
            import com.adobe.serialization.json.JSON;
            import flash.net.navigateToURL;
            import mx.events.FlexEvent;
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.InvokeEvent;
            import mx.rpc.events.ResultEvent;
            import spark.effects.easing.Linear;
            import spark.events.IndexChangeEvent;
            //クリエイションハンドラー
            protected function view1_creationCompleteHandler(event:FlexEvent):void
            {
                myLoading.visible = true;
                addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
                hts.send();
            }
            //HttpServiceの完了イベント
            protected function hts_resultHandler(event:ResultEvent):void
            {
                myLoading.visible = false;
                var obj:Object = JSON.decode(event.result.toString());
                myArr.source = obj as Array;
            }
            protected function hts_faultHandler(event:FaultEvent):void
            {
            }
            protected function hts_invokeHandler(event:mx.rpc.events.InvokeEvent):void
            {
            }
            protected function list_changeHandler(event:IndexChangeEvent):void
            {
                navigator.useDefaultTransitions = false;
                navigator.pushView(DetailView, list.selectedItem);
            }
            //キーボードハンドラー
            protected function onKeyDown(event:KeyboardEvent):void
            {
                if (event.keyCode == Keyboard.BACK)
                {
                }
                else if (event.keyCode == Keyboard.MENU)
                {
                    myMenu.visible = true;
                }
                else if (event.keyCode == Keyboard.SEARCH)
                {
                }
            }
            //メニューボタン処理
            protected function homeBtn_clickHandler(event:Event):void
            {
                myMenu.visible = false;
            }
            protected function rankBtn_clickHandler(event:Event):void
            {
                myMenu.visible = false;
            }
            protected function historyBtn_clickHandler(event:Event):void
            {
                myMenu.visible = false;
            }
            protected function gpsBtn_clickHandler(event:Event):void
            {
                myMenu.visible = false;
            }
            //リストの表示部分の整理
            protected function setLabel(item:Object):String
            {
                return item.todouhuken +' '+ String( item.name ).replace('amp;' , '' );
            }
        ]]>
    </fx:Script>
    <fx:Declarations>
        <s:ArrayCollection id="myArr"/>
        <s:HTTPService id="hts" url="http://moeten.info/maidcafe/json.php?m=movie"
                       result="hts_resultHandler(event)" fault="hts_faultHandler(event)" invoke="hts_invokeHandler(event)"
                       resultFormat="text"/>
    </fx:Declarations>
    <!--動画リスト表示-->
    <s:List id="list" width="100%" height="100%"
            change="list_changeHandler(event)"
            dataProvider="{myArr}" labelFunction="{setLabel}"
            >
        <s:itemRenderer>
            <fx:Component>
                <s:MobileIconItemRenderer
                    selectionColor="0x333333"
                    creationCompleteEffect="Fade"
                    iconField="thumbnail_url"
                    iconWidth="120"
                    iconHeight="100"
                    height="110"
                    fontSize="16" fontWeight="normal"
                    messageField="title"
                    />
            </fx:Component>
        </s:itemRenderer>
    </s:List>
    <!--メニューの実装。まだ動作しません-->
    <s:Group id="myMenu" height="110" width="100%" visible="false" bottom="0" showEffect="Fade" hideEffect="Fade">
        <s:Rect width="100%" height="100%">
            <s:fill>
                <s:SolidColor color="0x000000" alpha="0.6"/>
            </s:fill>
        </s:Rect>
        <s:HGroup paddingTop="5" paddingRight="5" paddingBottom="5" paddingLeft="5" width="100%" height="100%">
        <s:Button id="homeBtn"  label="新着" width="25%" height="100" click="homeBtn_clickHandler(event)"/>
        <s:Button id="rankBtn"  label="人気" width="25%" height="100" click="rankBtn_clickHandler(event)"/>
        <s:Button id="historyBtn"  label="履歴" width="25%" height="100" click="historyBtn_clickHandler(event)"/>
        <s:Button id="gpsBtn"  label="GPS" width="25%" height="100" click="gpsBtn_clickHandler(event)"/>
        </s:HGroup>
    </s:Group>
    <!--ローディング画面-->
    <s:Group id="myLoading" horizontalCenter="0" verticalCenter="0" showEffect="Fade" creationCompleteEffect="Fade" hideEffect="Fade" visible="false">
        <s:Rect width="200" height="200" radiusX="10" radiusY="10">
            <s:fill>
                <s:SolidColor color="0x000000" alpha="0.9"/>
            </s:fill>
        </s:Rect>
        <s:Label text="読み込み中"  horizontalCenter="0" verticalCenter="0"/>
    </s:Group>
</s:View>

detailView.mxml

動画の詳細と関連動画を表示します。

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark"
        xmlns:mx="library://ns.adobe.com/flex/mx"
        title="{String(data.name).replace('amp;','')}"
        creationComplete="view1_creationCompleteHandler(event)"
        viewActivate="refresh()"
        >
    <fx:Script>
        <![CDATA[
            import com.adobe.serialization.json.JSON;
            import flash.net.navigateToURL;
            import mx.events.FlexEvent;
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.InvokeEvent;
            import mx.rpc.events.ResultEvent;
            import spark.effects.easing.Linear;
            import spark.events.IndexChangeEvent;
            public function refresh():void
            {
            }
            //完了イベント
            protected function view1_creationCompleteHandler(event:FlexEvent):void
            {
                hts.send();
                //mySound.play();
                if( myTitle.width >= 460 ){
                    myMove.play();
                }
            }
            //HttpService管理用イベント。こちらのお店の動画リストを表示する
            protected function hts_resultHandler(event:ResultEvent):void
            {
                var obj:Object = JSON.decode(event.result.toString());
                myArr.source = obj as Array;
            }
            protected function hts_faultHandler(event:FaultEvent):void
            {
            }
            protected function hts_invokeHandler(event:mx.rpc.events.InvokeEvent):void
            {
            }
            //リストから動画再生
            protected function list_changeHandler(event:IndexChangeEvent):void
            {
                navigateToURL( new URLRequest( list.selectedItem.youtube_url ) );
            }
            //動画を再生
            protected function thumbnail_clickHandler(event:MouseEvent):void
            {
                navigateToURL( new URLRequest( data.youtube_url ) );
            }
            //リストのラベル整理
            protected function setLabel(item:Object):String
            {
                return String( item.name ).replace('amp;' , '' );
            }
            //公式サイトへGO!
            protected function urlBtn_clickHandler(event:MouseEvent):void
            {
                navigateToURL(new URLRequest( data.url ) );
            }
        ]]>
    </fx:Script>
    <fx:Declarations>
        <mx:SoundEffect id="mySound" target="{this}" source="assets/sound.mp3" useDuration="false"/>
        <s:Parallel id="myMove" repeatCount="0" target="{myTitle}">
            <s:Move xFrom="460" xTo="{-myTitle.width}" easer="{new Linear()}" duration="20000" />
        </s:Parallel>
        <s:ArrayCollection id="myArr"/>
        <s:HTTPService id="hts" url="{'http://moeten.info/maidcafe/json.php?m=movie&amp;sid=' + data.sid}"
                       result="hts_resultHandler(event)" fault="hts_faultHandler(event)" invoke="hts_invokeHandler(event)"
                       resultFormat="text"/>
    </fx:Declarations>
    <s:layout>
        <s:VerticalLayout horizontalAlign="center" paddingTop="10" paddingBottom="10" />
    </s:layout>
    <!--動画情報-->
    <s:Group width="460" clipAndEnableScrolling="true">
        <s:Rect width="460" height="40" radiusX="10" radiusY="10">
            <s:fill >
                <s:SolidColor color="0x333333"/>
            </s:fill>
            <s:stroke>
                <s:SolidColorStroke color="0x000000"/>
            </s:stroke>
        </s:Rect>
        <s:Label id="myTitle" text="{data.title}" verticalCenter="0"/>
    </s:Group>
    <s:HGroup>
        <s:Image id="thumbnail" width="198" height="149" source="{data.thumbnail_url}" click="thumbnail_clickHandler(event)"/>
        <s:Scroller height="145" width="250">
        <s:VGroup clipAndEnableScrolling="true" paddingLeft="10">
            <s:Label width="240" text="{data.description}" fontSize="17"/>
        </s:VGroup>
        </s:Scroller>
    </s:HGroup>
    <!--動画リスト-->
    <s:Group width="460">
        <s:Rect width="460" height="40" radiusX="10" radiusY="10">
            <s:fill >
                <s:SolidColor color="0x333333"/>
            </s:fill>
            <s:stroke>
                <s:SolidColorStroke color="0x000000"/>
            </s:stroke>
        </s:Rect>
        <s:Label text="こちらのお店の動画リスト" color="0xffffff" horizontalCenter="0" verticalCenter="0"/>
    </s:Group>
    <s:List id="list" width="460" height="100%"
            change="list_changeHandler(event)" dataProvider="{myArr}"
            lineHeight="0">
        <s:itemRenderer>
            <fx:Component>
                <s:MobileIconItemRenderer
                    iconField="thumbnail_url"
                    iconWidth="120" iconHeight="100" height="110"
                    fontSize="20" fontWeight="normal"
                    messageField="title" labelField=""
                    />
            </fx:Component>
        </s:itemRenderer>
    </s:List>
    <!--公式サイトへGO!-->
    <s:Button id="urlBtn" width="460" height="40" click="urlBtn_clickHandler(event)" label="公式サイトを見る"/>
</s:View>