Flex4 VideoDisplay全屏和部分控件全屏小例子

说明:这个例子包括了上一篇的videoDisplay的视频锯齿的处理,state状态的切换,控件全屏和部分控件全屏,双击单个视频全屏,那个全屏的按钮是所有视频的全屏,还有一个位置计算的方法

           刚学Flex不久,要做一个类似图中那样的视频展示网页。(代码写的太乱了真希望有大神可以帮忙优化!)


先看下效果图



1. main.mxml

   主页面

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx" width="960" height="530" xmlns:c="component.*"
			   initialize="init(event)" applicationComplete="applicationCompleteHandler(event)" backgroundColor="0x000000" >
	<fx:Declarations>
		<!-- 将非可视元素(例如服务、值对象)放在此处 -->
	</fx:Declarations>
	<s:states>
		<s:State name="one"/>
		<s:State name="two"/>
		<s:State name="three"/>
		<s:State name="four"/>
		<s:State name="five"/>
		<s:State name="six"/>
	</s:states>
	<fx:Script>
		<![CDATA[
			import mx.core.UIComponent;
			import mx.events.FlexEvent;
			
			import it.sephiroth.utils.HashMap;
			
			private var bId:String;
			private var vdAllArray:Array = null;
			private var stateArrayMap:HashMap = new HashMap();
			protected function init(event:FlexEvent):void
			{
				ExternalInterface.addCallback("changeState",changeState);
				
			}
			private var fullBlocks:int = 1;
			private function allFullScreen():void{
				this.fullScreen(this.getGroupId(Math.sqrt(fullBlocks)), 1);
			}
			private function singlefullScreen(event:MouseEvent):void{
				this.fullScreen(event.currentTarget as SVideoDisplay, 0);
			}
			
			private function fullScreen(displayObject:UIComponent, flag:int):void{
				if(FullScreenUtil.isFullScreen){
					FullScreenUtil.exitFullScreen();
					selectRect.width = 0;
					selectRect.height = 0;
				}else{
					FullScreenUtil.goFullScreen();
					if(flag == 0){
						// 加入要全屏的对像.videoDisplay
						FullScreenUtil.addChild(null, displayObject, true, true, true);
					}else{
						FullScreenUtil.addChild(stateArrayMap.getValue("map" + fullBlocks) as Array, displayObject, true, true, true);
					}
				}
			}
			
			private var stateMap:HashMap = new HashMap();
			private function changeState(gState:String, blocks:int):void{
//				vdAllArray = null;
				currentState = gState;
				if(stateMap.getValue(gState) == null){
					this.vdFitGroup(blocks);
					stateArrayMap.put("map" + blocks, vdAllArray);
				}
				selectRect.width = 0;
				selectRect.height = 0;
				fullBlocks = blocks;
				stateMap.put(gState, blocks);
			}
			
			private function getGroupId(sqrtBlocks:int):Group{
				var groupId:Group;
				if(1 == sqrtBlocks){
					groupId = oneVideo;
				} else if(2 == sqrtBlocks){
					groupId = twoVideo;
				}else if(3 == sqrtBlocks){
					groupId = threeVideo;
				}else if(4 == sqrtBlocks){
					groupId = fourVideo;
				}else if(5 == sqrtBlocks){
					groupId = fiveVideo;
				}else if(6 == sqrtBlocks){
					groupId = sixVideo;
				}
				
				return groupId;
			}
			private function vdFitGroup(blocks:int):void{
				var sumWidth:int = 960;	//容器宽度
				var sumHeight:int = 480;	//容器高度
				var cuttingLineWidht:int = 2;	//分割线宽
				var x:int = 2;	//相对X轴的距离
				var y:int = 2;	//相对Y轴的距离
				
				var sqrtBlocks:int = Math.sqrt(blocks); //取平方根
				var videoHeight:int = (sumHeight - (sqrtBlocks + 1) * 2) / sqrtBlocks;	//视频的高度
				var videoWidth:int = (sumWidth - (sqrtBlocks + 1) * 2) / sqrtBlocks; //视频的宽度
				var remainX:int = (sumWidth - (sqrtBlocks + 1) * 2) % sqrtBlocks; //X轴剩余的像素
				var remainY:int = (sumHeight - (sqrtBlocks + 1) * 2) % sqrtBlocks;	//Y轴剩余的像素
				var vd:SVideoDisplay = null;
				var vh:int;
				var vw:int;
				var hk:int = 0;
				vdAllArray = new Array();
				for(var i:int = 0; i < sqrtBlocks; i++){ //行
					var wk:int = 0;
					if(i >= (sqrtBlocks - remainY + 1)){
						hk++;
					}
					vdAllArray[i] = new Array();
					for(var j:int = 0; j < sqrtBlocks; j++){ //列
						vd = new SVideoDisplay();
						if(remainX > 0 && j >= (sqrtBlocks - remainX)){
							vw = videoWidth + 1;
						} else {
							vw = videoWidth;
							
						}
						if(remainY > 0 && i >= (sqrtBlocks - remainY)){
							vh = videoHeight + 1;
						} else {
							vh = videoHeight
							
						}
						if(j >= (sqrtBlocks - remainX + 1)){
							wk++;
						}
						
						x = 2 + 2 * j + j * videoWidth + wk; //列相距X轴的距离公式
						y = 2 + 2 * i + i * videoHeight + hk; //行相距Y轴的距离公式
						
						vd.x = x;
						vd.y = y;
						vd.id = blocks + "" + i + "" + j;
						vd.videoURL = "http://helpexamples.com/flash/video/clouds.flv";
						vd.height = vh;
						vd.width = vw;
						vd.toolTip = blocks + "" + i + "" + j;
						vd.addEventListener(MouseEvent.CLICK, vdClick);
						vd.doubleClickEnabled = true;
						vd.addEventListener(MouseEvent.DOUBLE_CLICK,singlefullScreen);
						vdAllArray[i][j] = vd;
						this.getGroupId(sqrtBlocks).addElement(vd);
					}
				}
			}
			//点击视频窗口的时候重新画一个矩形包围视频
			private function vdClick(event:MouseEvent):void{
				selectRect.x = SVideoDisplay(event.currentTarget).x;
				selectRect.y = SVideoDisplay(event.currentTarget).y;
				selectRect.width = SVideoDisplay(event.currentTarget).width;
				selectRect.height = SVideoDisplay(event.currentTarget).height;
				
			}
			
			protected function applicationCompleteHandler(event:FlexEvent):void
			{
				// TODO Auto-generated method stub
				this.vdFitGroup(1);
				stateArrayMap.put("map" + 1, vdAllArray);
				stateMap.put("one", 1);
			}
			
		]]>
	</fx:Script>
	
	
	<!-- 视频容器 -->
	<s:Group id="oneVideo" height="480" width="100%" includeIn="one">
	</s:Group>
	<s:Group id="twoVideo" height="480" width="100%" includeIn="two">
	</s:Group>
	<s:Group id="threeVideo" height="480" width="100%" includeIn="three">
	</s:Group>
	<s:Group id="fourVideo" height="480" width="100%" includeIn="four">
	</s:Group>
	<s:Group id="fiveVideo" height="480" width="100%" includeIn="five">
	</s:Group>
	<s:Group id="sixVideo" height="480" width="100%" includeIn="six">
	</s:Group>
	
	<!-- 选择框 -->
	<s:Rect id="selectRect">
		<s:stroke>
			<s:SolidColorStroke color="0xff0000" weight="2" />
		</s:stroke> 
	</s:Rect>
	<s:BorderContainer x="0" y="480" height="50" width="960" borderColor="0xff0000">
		<s:layout>
			<s:HorizontalLayout/>
		</s:layout>
		<s:Button name="one" label="1" click="changeState(event.currentTarget.name, 1)"/>
		<s:Button name="two" label="4" click="changeState(event.currentTarget.name, 4)"/>
		<s:Button name="three" label="9" click="changeState(event.currentTarget.name, 9)"/>
		<s:Button name="four" label="16" click="changeState(event.currentTarget.name, 16)"/>
		<s:Button name="five" label="25" click="changeState(event.currentTarget.name, 25)"/>
		<s:Button name="six" label="36" click="changeState(event.currentTarget.name, 36)"/>
		<s:Button label="全屏" click="allFullScreen();"/>
	</s:BorderContainer>
</s:Application>

2. SVideoDisplay.mxml

    自定义组件为VideoDisplay设置背景色,并且动态绑定一个source属性,还有视频锯齿的处理

    还有一个原因就是因为VideoDisplay如果视频源为空的话,他这个对象就为空,到时候需要点击的时候就获取不到

<?xml version="1.0" encoding="utf-8"?>
<s:BorderContainer xmlns:fx="http://ns.adobe.com/mxml/2009"
				   xmlns:s="library://ns.adobe.com/flex/spark"
				   xmlns:mx="library://ns.adobe.com/flex/mx"
				   backgroundColor="#999999" borderVisible="false" width="400" height="200">
	<fx:Declarations>
		<!-- 将非可视元素(例如服务、值对象)放在此处 -->
	</fx:Declarations>
	
	<fx:Script>
		<![CDATA[
			
			import spark.components.VideoDisplay;
			
			/**
			 *自定义视频url属性 ,因为这个视频源要动态的,所以加了个_videoURL属性用来动态绑定他(不知道这样合不合理)
			 * */
			[Bindable]
			private var _videoURL:String = "";
			
			public function set videoURL(url:String):void{
				this._videoURL=url;
			}
			public function get videoURL():String{
				return this._videoURL;
			}
			
			
			import org.osmf.events.MediaPlayerStateChangeEvent;
			private function checkState(e:MediaPlayerStateChangeEvent):void{
				if(e.state == "playing") 
					vid_player.videoObject.smoothing = true;
			}
			
		]]>
	</fx:Script>
	
	<s:VideoDisplay id="vid_player" width="100%" height="100%" source="{_videoURL}" scaleMode="stretch"  mediaPlayerStateChange="checkState(event)" />
		
</s:BorderContainer>


FullScreenUtil.as

  网上的一个全屏的as类,自己加了一些代码进去

package 
{
	import flash.display.DisplayObject;
	import flash.display.StageDisplayState;
	import flash.events.FullScreenEvent;
	import flash.utils.Dictionary;
	
	import mx.containers.Canvas;
	import mx.core.FlexGlobals;
	import mx.core.IVisualElementContainer;
	import mx.core.UIComponent;
	import mx.events.ResizeEvent;
	import mx.managers.PopUpManager;
	
	public class FullScreenUtil
	{
		private static var theCanvas:Canvas;
		private static var displayObjectMap:Dictionary = new Dictionary(true);
		private static var anchorMap:Dictionary = new Dictionary(true);
		private static var _canvasStyleName:String = null;
		
		public static var isFullScreen:Boolean = false;
		private static var displayObjectArr:Array = new Array(); //自定义一个数组
		
		/**
		 *Getters and setters to facilitate styling the background canvas 
		 * @param val
		 * 
		 */		
		public static function set canvasStyleName(val:String):void{
			_canvasStyleName = val;
		}
		
		public static function get canvasStyleName():String{
			return _canvasStyleName;
		}
		
		/**
		 *Use this method to send the application full screen 
		 * @param color color for the full screen background to be
		 * 
		 */		
		public static function goFullScreen(color:uint = 0x000000):void{
			isFullScreen = true;
			theCanvas = new Canvas();
			theCanvas.mouseEnabled = false;
			
			if(canvasStyleName){
				theCanvas.styleName = canvasStyleName;
			}else{
				theCanvas.setStyle('backgroundColor', color);				
			}
			
			PopUpManager.addPopUp(theCanvas, FlexGlobals.topLevelApplication as DisplayObject);
			
			FlexGlobals.topLevelApplication.stage.displayState = StageDisplayState.FULL_SCREEN;
			
			onResize();
			
			(FlexGlobals.topLevelApplication as DisplayObject).addEventListener(ResizeEvent.RESIZE, onResize);
			theCanvas.systemManager.stage.addEventListener(FullScreenEvent.FULL_SCREEN, onExitFullScreen);
		}
		
		
		/**
		 *Use this method to exit full screen 
		 * all cleanup and child parenting will be done automatically
		 */		
		public static function exitFullScreen():void{
			isFullScreen = false;
			if(!theCanvas)return;
			if(null != displayObjectArr){
				vdFitWindow(960, 480, displayObjectArr.length*displayObjectArr.length);
			} else {
			}
			
			(FlexGlobals.topLevelApplication as DisplayObject).removeEventListener(ResizeEvent.RESIZE, onResize);
			theCanvas.systemManager.stage.removeEventListener(FullScreenEvent.FULL_SCREEN, onExitFullScreen);
			if(theCanvas.systemManager.stage.displayState == StageDisplayState.FULL_SCREEN)theCanvas.systemManager.stage.displayState = StageDisplayState.NORMAL;
			PopUpManager.removePopUp(theCanvas);
			readdChildred();
			theCanvas = null;
		}
		
		/**
		 *Use this method to addchildren to the full screen instance after you've called the <code>goFullScreen()</code> method
		 * if you strech proportionally without anchoring the object will be moved to 0,0 in the canvas' coordinate space 
		 * @param displayObject - display object to be added
		 * @param centerHorizontally - whether to center horizontally in the canvas space
		 * @param centerVertically - whether to center vertically in the canvas space
		 * @param stretchProportional - whether to stretch proportionally to cover all of the space
		 * @param anchorLeft - left anchor
		 * @param anchorRight - right anchor
		 * @param anchorTop - top anchor
		 * @param anchorBottom - bottom anchor
		 * 
		 */		
		public static function addChild(arr:Array, displayObject:UIComponent, centerHorizontally:Boolean = false, centerVertically:Boolean = false, stretchProportional:Boolean = false, anchorLeft:Number = -1, anchorRight:Number = -1, anchorTop:Number = -1, anchorBottom:Number = -1 ):void{
			if(!theCanvas)return;
			var infoObject:Object = new Object();
			infoObject['parent'] = displayObject.parent;
			infoObject['x'] = displayObject.x;
			infoObject['y'] = displayObject.y;
			infoObject['width'] = displayObject.width;
			infoObject['height'] = displayObject.height;
			infoObject['percentWidth'] = displayObject.percentWidth
			infoObject['percentHeight'] = displayObject.percentHeight;
			
			//获取组件在原先的父级上的索引
			if(displayObject.parent){
				if (displayObject.parent is IVisualElementContainer){
					var ivec:IVisualElementContainer = IVisualElementContainer(displayObject.parent);
					infoObject['childIndex'] = ivec.getElementIndex(displayObject);
					ivec.removeElement(displayObject);
				}else{
					infoObject['childIndex'] = displayObject.parent.getChildIndex(displayObject);
					displayObject.parent.removeChild(displayObject);
				}
			}
			
			//自定义
			displayObjectArr = arr;
			if(null != arr){
				vdFitWindow(theCanvas.width, theCanvas.height, displayObjectArr.length*displayObjectArr.length);
			} else {
			}
			
			displayObjectMap[displayObject] = infoObject;
			
			var anchorObject:Object = new Object();
			anchorObject['stretchProportional'] = stretchProportional;
			anchorObject['anchorLeft'] = anchorLeft;
			anchorObject['anchorRight'] = anchorRight;
			anchorObject['anchorTop'] = anchorTop;
			anchorObject['anchorBottom'] = anchorBottom;
			anchorObject['centerVertically'] = centerVertically;
			anchorObject['centerHorizontally'] = centerHorizontally;
			anchorMap[displayObject] = anchorObject;
			
			
			theCanvas.addChild(displayObject);
			
			onResize();
		}
		
		
		/**
		 *Remove a child explicitly from the full screen view
		 * cleanup is done, and it is reparented 
		 * @param displayObject - child to be removed
		 * 
		 */		
		public static function removeChild(displayObject:UIComponent):void{
			var uic:UIComponent = displayObject as UIComponent;
			var infoObject:Object = displayObjectMap[uic];
			if(!infoObject)return;
			if(infoObject['parent']){
				
				// add back to original parent
				if (infoObject.parent is IVisualElementContainer)
					infoObject.parent.addElementAt(uic, infoObject['childIndex']);
				else
					infoObject.parent.addChildAt(uic, infoObject['childIndex']);
				
				if(isNaN(infoObject['percentWidth'])){
					uic.width = infoObject['width'];
				}else{
					uic.percentWidth = infoObject['percentWidth'];
				}
				if(isNaN(infoObject['percentHeight'])){
					uic.height = infoObject['height'];
				}else{
					uic.percentHeight = infoObject['percentHeight'];
				}
				uic.x = infoObject['x'];
				uic.y = infoObject['y'];
				delete displayObjectMap[uic];
				delete anchorMap[uic];
			}
		}
		
		/**
		 *Readds all children to their correct containers
		 * used when we're exiting full screen 
		 * 
		 */		
		private static function readdChildred():void{
			for(var key:Object in displayObjectMap){
				if(key is UIComponent){
					removeChild(key as UIComponent);
				}
			}
		}
		
		/**
		 *Called on resize to update the coordinates of anchored children throughout the canvas 
		 * 
		 */		
		private static function updateAnchorStates():void{
			for(var key:Object in anchorMap){
				if(key is UIComponent){
					var uic:UIComponent = key as UIComponent;
					var anchorObject:Object = anchorMap[key];
					var stretchProportional:Boolean = anchorObject['stretchProportional'] as Boolean;
					var anchorLeft:Number = anchorObject['anchorLeft'] as Number;
					var anchorRight:Number = anchorObject['anchorRight'] as Number;
					var anchorTop:Number = anchorObject['anchorTop'] as Number;
					var anchorBottom:Number = anchorObject['anchorBottom'] as Number;
					var centerVertically:Boolean = anchorObject['centerVertically'] as Boolean;
					var centerHorizontally:Boolean = anchorObject['centerHorizontally'] as Boolean;
					
					if(stretchProportional){
						var w:Number = uic.width;
						var h:Number = uic.height;
						var sw:Number = FlexGlobals.topLevelApplication.screen.width;
						var sh:Number = FlexGlobals.topLevelApplication.screen.height;
						if(w > h){
							uic.width = sw;
							uic.validateNow();
							//高直接用屏幕的高度
							//							uic.height *= (uic.width / w);
							uic.height = sh;
							uic.validateNow();
						}else{
							uic.height = sh;
							uic.validateNow();
							uic.width *= (uic.height / h);
							uic.validateNow();
						}
				
					}
					
					if(anchorLeft != -1){
						uic.x = anchorLeft;
					}
					
					if(anchorRight != -1){
						uic.x = FlexGlobals.topLevelApplication.screen.width - uic.width - anchorRight;
					}
					
					if(anchorTop != -1){
						uic.y = anchorTop;
					}
					
					if(anchorBottom != -1){
						uic.y = FlexGlobals.topLevelApplication.screen.height - uic.height - anchorBottom;
					}
					
					if(anchorLeft == -1 && anchorRight == -1 && stretchProportional)uic.x = 0;
					if(anchorTop == -1 && anchorBottom == -1 && stretchProportional)uic.y = 0;
					
					if(centerVertically)uic.y = FlexGlobals.topLevelApplication.screen.height / 2 - uic.height / 2;
					if(centerHorizontally)uic.x = FlexGlobals.topLevelApplication.screen.width / 2 - uic.width / 2;
				}
			}
		}
		
		
		/**
		 *When the application is resized 
		 * @param event
		 * 
		 */		
		private static function onResize(event:ResizeEvent = null):void{
			if(!theCanvas)return;
			theCanvas.width = FlexGlobals.topLevelApplication.screen.width;
			theCanvas.height = FlexGlobals.topLevelApplication.screen.height;
			theCanvas.validateNow();
			updateAnchorStates();
		}
		
		/**
		 *When full screen is exited with the escape key this will be triggered 
		 * @param e
		 * 
		 */		
		private static function onExitFullScreen(e:FullScreenEvent):void{
			if(e != null && !e.fullScreen)exitFullScreen();
		}
		
		/**
		 * 自己定义的方法,全屏的时候计算容器内子控件的位置
		 * 
		 */
		private static function vdFitWindow(width:int, height:int, block:int):void{
			var sumWidth:int = width;	//容器宽度
			var sumHeight:int = height;	//容器高度
			var cuttingLineWidht:int = 2;	//分割线宽
			var blocks:int = block;	//几屏 1,4,9,16,25,36
			var x:int = 2;	//相对X轴的距离
			var y:int = 2;	//相对Y轴的距离
			
			var sqrtBlocks:int = Math.sqrt(blocks); //取平方根
			var videoHeight:int = (sumHeight - (sqrtBlocks + 1) * 2) / sqrtBlocks;	//视频的高度
			var videoWidth:int = (sumWidth - (sqrtBlocks + 1) * 2) / sqrtBlocks; //视频的宽度
			var remainX:int = (sumWidth - (sqrtBlocks + 1) * 2) % sqrtBlocks; //X轴剩余的像素
			var remainY:int = (sumHeight - (sqrtBlocks + 1) * 2) % sqrtBlocks;	//Y轴剩余的像素
			var vh:int;
			var vw:int;
			var hk:int = 0;
			
			for(var i:int = 0; i < sqrtBlocks; i++){ //行
				var wk:int = 0;
				if(i >= (sqrtBlocks - remainY + 1)){
					hk++;
				}
				for(var j:int = 0; j < sqrtBlocks; j++){ //列
					if(remainX > 0 && j >= (sqrtBlocks - remainX)){
						vw = videoWidth + 1;
					} else {
						vw = videoWidth;
						
					}
					if(remainY > 0 && i >= (sqrtBlocks - remainY)){
						vh = videoHeight + 1;
					} else {
						vh = videoHeight
						
					}
					if(j >= (sqrtBlocks - remainX + 1)){
						wk++;
					}
					
					x = 2 + 2 * j + j * videoWidth + wk; //列相距X轴的距离公式
					y = 2 + 2 * i + i * videoHeight + hk; //行相距Y轴的距离公式
					
					var vd:SVideoDisplay = SVideoDisplay(displayObjectArr[i][j]);
					vd.x = x;
					vd.y = y;
					vd.height = vh;
					vd.width = vw;
				}
			}
		}
		
	}
}

还有一个swc包,这个是别人实现的一个hashmap 

到这里来下载 http://download.csdn.net/detail/soanl/6877289


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值