Binyy Wuhan

i love Flex i come from Wuhan

导航

Flex【原创】移动设备相册图片浏览功能

Flex【原创】移动设备相册图片浏览功能 

 

Flex实现移动设备相册图片浏览功能

Flex4.6(IOS/Android)

首先贴上代码结构图:

 

分析2个重要视图:

1:ScanListView 作为firstView,用List呈现一个相片列表

View Code
<?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="照片列表"
        creationComplete="creationCompleteHandler(event)">
    <fx:Declarations>
        <s:ArrayCollection id="imgdata">
            <fx:Object source="assets/images/1.jpg" message="assets/images/1.jpg" name="sample1"/>
            <fx:Object source="assets/images/3.jpg" message="assets/images/2.jpg" name="sample2"/>
            <fx:Object source="assets/images/4.jpg" message="assets/images/3.jpg" name="sample3"/>
            <fx:Object source="assets/images/5.jpg" message="assets/images/4.jpg" name="sample4"/>
            <fx:Object source="assets/images/6.jpg" message="assets/images/5.jpg" name="sample5"/>
            <fx:Object source="assets/images/7.jpg" message="assets/images/6.jpg" name="sample6"/>
            <fx:Object source="assets/images/8.jpg" message="assets/images/7.jpg" name="sample7"/>
            <fx:Object source="assets/images/9.jpg" message="assets/images/8.jpg" name="sample8"/>
            <fx:Object source="assets/images/10.jpg" message="assets/images/9.jpg" name="sample9"/>
            <fx:Object source="assets/images/11.jpg" message="assets/images/10.jpg" name="sample10"/>
            <fx:Object source="assets/images/12.jpg" message="assets/images/11.jpg" name="sample11"/>
            <fx:Object source="assets/images/13.jpg" message="assets/images/12.jpg" name="sample12"/>
            <fx:Object source="assets/images/14.jpg" message="assets/images/13.jpg" name="sample13"/>
            <fx:Object source="assets/images/15.jpg" message="assets/images/14.jpg" name="sample14"/>
            <fx:Object source="assets/images/17.jpg" message="assets/images/16.jpg" name="sample15"/>
            <fx:Object source="assets/images/18.jpg" message="assets/images/17.jpg" name="sample16"/>
            <fx:Object source="assets/images/19.jpg" message="assets/images/18.jpg" name="sample17"/>
            <fx:Object source="assets/images/20.jpg" message="assets/images/19.jpg" name="sample18"/>
        </s:ArrayCollection>
    </fx:Declarations>
    <fx:Script>
        <![CDATA[
            import com.yyf.model.MainModelLocator;
            
            import mx.events.FlexEvent;
            
            [Bindable]private var mainModel:MainModelLocator = MainModelLocator.getInstance();
            
            protected function creationCompleteHandler(event:FlexEvent):void
            {
                mainModel.dataProvider = imgdata;
            }
            
            protected function list_clickHandler(event:MouseEvent):void
            {
                mainModel.selectedIndex = imgList.selectedIndex;
                navigator.pushView(ScanTabView ,null,null,mainModel.xFadeTrans);
            }
            
        ]]>
    </fx:Script>
    <s:List id="imgList" dataProvider="{mainModel.dataProvider}" width="100%" height="100%"
            horizontalScrollPolicy="off" verticalScrollPolicy="on"
            click="list_clickHandler(event)">
        <s:layout>
            <!--<s:TileLayout columnWidth="{this.width / 3}" rowHeight="{this.width / 3}" horizontalGap="0" verticalGap="0"/>-->
            <s:VerticalLayout gap="0" horizontalAlign="center" verticalAlign="middle"/>
        </s:layout>
        <s:itemRenderer>
            <fx:Component>
<!--                <s:ItemRenderer 
                    mouseDown="sc.color = 0xFED913" 
                    mouseUp="sc.color = 0x030303" 
                    mouseOut="sc.color = 0x030303">
                    <s:Rect top="0" bottom="0" left="0" right="0">
                        <s:fill>
                            <s:SolidColor id="sc" color="0x030303"/>
                        </s:fill>
                    </s:Rect>
                    <s:BitmapImage source="{data.source}" width="90%" height="90%" horizontalCenter="0" verticalCenter="0"/>
                </s:ItemRenderer>-->
                <s:IconItemRenderer iconWidth="80" iconHeight="80" width="100%"
                                    messageField="message" messageStyleName="articleFontStyle"
                                    iconField="source" labelField="name" 
                                    decorator="@Embed(source='/assets/icons/sanjiao.png')">
                </s:IconItemRenderer> 
            </fx:Component>
        </s:itemRenderer>
    </s:List>
</s:View>

 

2: ScanTabView 点击List的子元素进入手势左右切换浏览相片视图

View Code
<?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="{mainModel.controlType == Config.IMAGE_TAB ? '照片列表' : '详细信息'}" 
        xmlns:scan="com.yyf.view.scan.*"
        removedFromStage="removedFromStageHandler(event)">
    <fx:Script>
        <![CDATA[
            import com.yyf.model.MainModelLocator;
            import com.yyf.util.Config;
            
            import mx.events.FlexEvent;
            [Bindable]private var mainModel:MainModelLocator = MainModelLocator.getInstance();
            protected function acbtn_clickHandler(event:MouseEvent):void
            {
                switch(mainModel.controlType)
                {
                    case Config.IMAGE_TAB :
                        mainModel.controlType = Config.IMAGE_DETAIL;
                        sv.removeTabEventListeners();
                        sv.imgG.addGestureEventListeners();
                        sv.reset();
                        break;
                    case Config.IMAGE_DETAIL :
                        mainModel.controlType = Config.IMAGE_TAB;
                        sv.addTabEventListeners();
                        sv.imgG.removeGestureEventListeners();
                        sv.reset();
                        break;
                    default :
                        break;
                }
            }
            
            protected function removedFromStageHandler(event:Event):void
            {
                mainModel.controlType = Config.IMAGE_TAB;
                sv.imgG.removeGestureEventListeners();
                sv.addTabEventListeners();
            }
            
        ]]>
    </fx:Script>
    <fx:Declarations>
    </fx:Declarations>
    <s:actionContent>
        <s:Button id="acbtn" label="{mainModel.controlType == Config.IMAGE_TAB ? '操作' : '返回'}" click="acbtn_clickHandler(event)"/>
        <s:Button id="backbtn" label="返回" click="navigator.popView(mainModel.xFadeTrans);"
                  includeInLayout="{mainModel.controlType == Config.IMAGE_TAB ? true : false}"
                  visible="{mainModel.controlType == Config.IMAGE_TAB ? true : false}"/>
    </s:actionContent>
    <scan:ScanView id="sv" width="100%" height="100%" dataProvider="{mainModel.dataProvider}" selectedIndex="{mainModel.selectedIndex}"/>
</s:View>

 

分析2个重要组件:

1:ScanView 呈现照片的容器 封装手势左右切换相片的相关事件

View Code
<?xml version="1.0" encoding="utf-8"?>
<s:SkinnableContainer xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" 
        xmlns:scan="com.yyf.view.scan.*"
        creationComplete="view_creationCompleteHandler(event)"
        mouseEnabled="{active}"
        enabled="{active}">
    <fx:Declarations>
        <s:Fade id="imgFade" target="{imgG}" alphaFrom="0.0" alphaTo="1.0"/>
        <s:Fade id="focusIn" target="{pageNotice}" alphaFrom="0.0" alphaTo="1.0"/>
        <s:Fade id="focusOut" target="{pageNotice}" alphaFrom="1.0" alphaTo="0.0"/>
        <s:Image id="pageNotice"  buttonMode="true"  click="pagePrompt_clickHandler(event)" filters="{[dropShadow]}"/>
        <s:DropShadowFilter id="dropShadow" alpha="0.8" blurX="8" blurY="8" distance="0" color="#030303" angle="360" />
    </fx:Declarations>
    <fx:Script>
        <![CDATA[
            import com.yyf.model.MainModelLocator;
            import com.yyf.util.Config;
            
            import mx.collections.ArrayCollection;
            import mx.events.FlexEvent;
            import mx.managers.PopUpManager;
            
            [Bindable]
            [Embed(source="assets/icons/firstPage.png")]
            private var firsttImgClass:Class;
            
            [Bindable]
            [Embed(source="assets/icons/lastPage.png")]
            private var lastImgClass:Class;
            
            [Bindable]public var dataProvider:ArrayCollection;
            [Bindable]public var selectedIndex:int = 0;
            [Bindable]private var active:Boolean = true;
            private var runing:Boolean = false;
            private var oldPoint:Point;
            private const movePrecision:Number=30;//滑动翻页精度
            
            [Bindable]private var mainModel:MainModelLocator = MainModelLocator.getInstance();
            
            protected function view_creationCompleteHandler(event:FlexEvent):void
            {
                this.imgG.imgMaxWidth = this.width - 15;
                this.imgG.imgMaxHeight = this.height - 10;
                addTabEventListeners();
            }
            
            public function addTabEventListeners():void
            {
                if(!this.hasEventListener(MouseEvent.MOUSE_MOVE))
                    this.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
                if(!this.hasEventListener(MouseEvent.MOUSE_UP))
                    this.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
            }
            
            public function removeTabEventListeners():void
            {
                if(this.hasEventListener(MouseEvent.MOUSE_MOVE))
                    this.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
                if(this.hasEventListener(MouseEvent.MOUSE_UP))
                    this.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
            }
            
            protected function mouseMoveHandler(event:MouseEvent):void
            {
                if(event.buttonDown&&!runing){
                    runing = true;
                    oldPoint = new Point(event.stageX,event.stageY);
                    this.mouseChildren = false;
                }
            }
            
            protected function mouseUpHandler(event:MouseEvent):void
            {
                if(runing){
                    this.mouseChildren = true;
                    runing = false;
                    if((event.stageX - oldPoint.x) > movePrecision){//right
                        prev();
                    }else if((event.stageX - oldPoint.x) < movePrecision){//left
                        next();
                    }
                }
            }
            
            private function prev():void{
                if(selectedIndex == 0)
                {
                    selectedIndex = 0;
                    active = false;
                    mblbl.visible = true;
                    pageNotice.source = firsttImgClass;
                    PopUpManager.addPopUp(pageNotice,this);
                    PopUpManager.centerPopUp(pageNotice);
                    focusIn.end();
                    focusIn.play();
                    return;
                }
                selectedIndex--;
                imgFade.end();
                imgFade.play();
            }
            
            private function next():void{
                if(selectedIndex == dataProvider.length - 1)
                {
                    selectedIndex = dataProvider.length - 1;
                    active = false;
                    mblbl.visible = true;
                    pageNotice.source = lastImgClass;
                    PopUpManager.addPopUp(pageNotice,this);
                    PopUpManager.centerPopUp(pageNotice);
                    focusIn.end();
                    focusIn.play();
                    return;
                }
                selectedIndex++;
                imgFade.end();
                imgFade.play();
            }
            
            protected function pagePrompt_clickHandler(event:MouseEvent):void
            {
                active = true;
                focusOut.end();
                focusOut.play();
                pageNotice.source = null;
                mblbl.visible = false;
            }
            
            public function reset():void{
                imgG.scaleX = 1.0;
                imgG.scaleY = 1.0;
                imgG.rotation = 0;
            }
            
        ]]>
    </fx:Script>
    <scan:ImageView id="imgG" source="{dataProvider.getItemAt(selectedIndex).source}" maxScale="3.0" minScale="0.5"/>
    <!--show button when turn page to the last or first one-->
    <s:Label id="mblbl" width="100%" height="100%" visible="false"/>
</s:SkinnableContainer>

 

2: ImageView 照片组件 封装对相片操作:缩放,旋转,平移的相关事件

View Code
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
             xmlns:s="library://ns.adobe.com/flex/spark"
             x="{img.x - 3}" y="{img.y - 3}" 
             width="{img.width + 6}" height="{img.height + 6}"
             horizontalCenter="0" verticalCenter="0">
    <fx:Script>
        <![CDATA[
            import com.yyf.model.MainModelLocator;
            import com.yyf.util.Config;
            import com.yyf.util.RotatableScalable;
            
            import mx.events.FlexEvent;
            
            import org.tuio.TuioManager;
            import org.tuio.adapters.NativeTuioAdapter;
            import org.tuio.gestures.DragGesture;
            import org.tuio.gestures.GestureManager;
            import org.tuio.gestures.RotateGesture;
            import org.tuio.gestures.TwoFingerMoveGesture;
            import org.tuio.gestures.ZoomGesture;
            
            [Bindable]public var source:* = null;
            [Bindable]public var imgMaxWidth:Number;
            [Bindable]public var imgMaxHeight:Number;
            
            public var minScale:Number = 0.8;
            public var maxScale:Number = 3.0;
            
            private var imgDragEnable:Boolean = false;
            
            [Bindable]private var mainModel:MainModelLocator = MainModelLocator.getInstance();
            
            protected function addedToStageHandler(event:Event):void
            {
                if(mainModel.gestureManagerInit)return;
                var tc:NativeTuioAdapter = new NativeTuioAdapter(stage);
                tc.addListener(TuioManager.init(stage));
                var tm:GestureManager = GestureManager.init(stage);
                addGestureManager();
                mainModel.gestureManagerInit = true;
            }
            
            protected function addGestureManager():void
            {
                GestureManager.addGesture(new DragGesture());
                GestureManager.addGesture(new ZoomGesture(TwoFingerMoveGesture.TRIGGER_MODE_TOUCH)); 
                GestureManager.addGesture(new RotateGesture(TwoFingerMoveGesture.TRIGGER_MODE_TOUCH));
            }
            
            public function addGestureEventListeners():void
            {
                if(!this.hasEventListener(TransformGestureEvent.GESTURE_PAN))
                    this.addEventListener(TransformGestureEvent.GESTURE_PAN, handleDrag);
                if(!this.hasEventListener(TransformGestureEvent.GESTURE_ZOOM))
                    this.addEventListener(TransformGestureEvent.GESTURE_ZOOM, handleScale);
                if(!this.hasEventListener(TransformGestureEvent.GESTURE_ROTATE))
                    this.addEventListener(TransformGestureEvent.GESTURE_ROTATE, handleRotate);
                this.horizontalCenter = this.verticalCenter = undefined;
                fadeIn.end();
                fadeIn.play();
            }
            
            public function removeGestureEventListeners():void
            {
                if(this.hasEventListener(TransformGestureEvent.GESTURE_PAN))
                    this.removeEventListener(TransformGestureEvent.GESTURE_PAN, handleDrag);
                if(this.hasEventListener(TransformGestureEvent.GESTURE_ZOOM))
                    this.removeEventListener(TransformGestureEvent.GESTURE_ZOOM, handleScale);
                if(this.hasEventListener(TransformGestureEvent.GESTURE_ROTATE))
                    this.removeEventListener(TransformGestureEvent.GESTURE_ROTATE, handleRotate);
                this.horizontalCenter = this.verticalCenter = 0; 
            }
            
            private function handleScale(e:TransformGestureEvent):void {
                var p:Point  = this.localToGlobal(new Point(e.localX, e.localY));
                p = parent.globalToLocal(p);
                var m:Matrix = this.transform.matrix;
                m.translate( -p.x, -p.y);
                m.scale(e.scaleX, e.scaleY);
                m.translate(p.x, p.y);
                this.transform.matrix = m;
                if (this.scaleX > maxScale) {
                    m = this.transform.matrix;
                    m.translate( -p.x, -p.y);
                    m.scale(maxScale/this.scaleX, maxScale/this.scaleY);
                    m.translate(p.x, p.y);
                    this.transform.matrix = m;
                } else if (this.scaleX < minScale) {
                    m = this.transform.matrix;
                    m.translate( -p.x, -p.y);
                    m.scale(minScale/this.scaleX, minScale/this.scaleY);
                    m.translate(p.x, p.y);
                    this.transform.matrix = m;
                }
            }
            
            private function handleRotate(e:TransformGestureEvent):void {
                var p:Point  = this.localToGlobal(new Point(e.localX, e.localY));
                p = parent.globalToLocal(p);
                var m:Matrix = this.transform.matrix;
                m.translate(-p.x, -p.y);
                m.rotate(e.rotation * (Math.PI / 180));
                m.translate(p.x, p.y);
                this.transform.matrix = m;
            }
            
            private function handleDrag(e:TransformGestureEvent):void {
                this.x += e.offsetX;
                this.y += e.offsetY;
            }
            
            private function stopImgDrag():void{
                if(!this.hasEventListener(TransformGestureEvent.GESTURE_PAN))
                {
                    this.addEventListener(TransformGestureEvent.GESTURE_PAN, handleDrag);
                    this.imgDragEnable = false;
                }
            }
            
            private function startImgDrag():void{
                if(this.hasEventListener(TransformGestureEvent.GESTURE_PAN))
                {
                    this.removeEventListener(TransformGestureEvent.GESTURE_PAN, handleDrag);
                    this.imgDragEnable = true;
                }
            }
            
        ]]>
    </fx:Script>
    <fx:Declarations>
        <s:Fade id="fadeIn" target="{boder}" alphaFrom="0.0" alphaTo="1.0"/>
    </fx:Declarations>
    <s:BorderContainer id="boder" left="-2" right="-2" bottom="-2" top="-2" cornerRadius="5" backgroundAlpha="0.0" visible="{mainModel.controlType == Config.IMAGE_TAB ? false : true}">
        <s:borderStroke> 
            <s:SolidColorStroke color="0xFED913" weight="5"/> 
        </s:borderStroke> 
    </s:BorderContainer>
    <s:Image id="img" source="{source}" maxWidth="{imgMaxWidth}" maxHeight="{imgMaxHeight}"
             horizontalCenter="0" verticalCenter="0"
             addedToStage="addedToStageHandler(event)"/>
</s:Group>

 

 效果图:

 

源码下载地址:https://files.cnblogs.com/loveFlex/Sample_ScanImage.rar

请大家多多指教~

posted on 2012-04-28 16:06  Binyy_Wuhan  阅读(3442)  评论(7编辑  收藏  举报