Статьи

Адаптивный интерфейс: мобильный против планшета

Размер экрана планшетного устройства намного больше, чем у смартфона. Это очень близко к настольному. Если вы планируете разработать мобильное приложение и запустить его на смартфонах и планшетах, вам необходимо адаптировать интерфейс(ваши взгляды) по нескольким причинам: пользовательский опыт, производительность и удобство использования. Обычно вы носите смартфон левой рукой и взаимодействуете с пальцами правой руки. Из-за размера и веса планшетов вы можете по-разному проектировать свои экраны, чтобы принимать взаимодействия в левой и правой частях экрана. В идеале, некоторые пользователи просто используют левый и правый большие пальцы для взаимодействия с вашим приложением. Форма BlackBerry PlayBook была создана для того, чтобы этот опыт «превью». В этом уроке я только что создал очень простое приложение. Это галерея изображений с двумя экранами: просмотр списка картинок и просмотр полной картинки. Чтобы обеспечить максимально эффективное взаимодействие с пользователем, я определил три возможных макета:

Целью этого проекта является обработка этих трех макетов в одном проекте, который будет адаптировать его макет в зависимости от размера и ориентации экрана. Я был вдохновлен презентацией Нью-Джерси, доступной в его блоге . В этом видео представлен окончательный результат на смартфонах и планшетах. Как видите, производительность приложения отличная на Android, iOS и PlayBook.

Штаты и группы

Чтобы адаптировать пользовательский интерфейс, начните с простых объявлений состояний. Используйте if stateGroups, если необходимо уменьшить размер кода, создав два основных семейства: «размеры экрана» (телефон, планшет) и «ориентация» (портрет, пейзаж) .

<s:states>
	<s:State name="portraitPhone" stateGroups="phone,portrait"/>
	<s:State name="landscapePhone" stateGroups="landscape,phone"/>
	<s:State name="portraitTablet" stateGroups="portrait,tablet"/>
	<s:State name="landscapeTablet" stateGroups="landscape,tablet"/>
</s:states>

Чтобы переключиться из одного состояния в другое, я просто слушаю события Resize.

protected function application1_resizeHandler(event:ResizeEvent):void
	{
 
		var isPortrait:Boolean = height > width;
		isTablet = height > 960 || width > 960;        
 
		currentState = (isPortrait ? "portrait" : "landscape") + (isTablet ? "Tablet" : "Phone");
	}

ViewNavigator x 2

Затем я добавляю две композиции ViewNavigator в мой основной <s: Application>. В этом случае я создаю Flex Mobile Project, но я не использую архитектуру ViewNavigatorApplication в качестве оболочки. Обратите внимание, что координаты, размеры и видимость компонентов viewNavigator зависят от состояний (и от групп состояний).

<!--TABLETS CENTERED VIEW-->
	<s:ViewNavigator includeIn="tablet"
		id="tabletPictureNavigator"
	        width.landscapeTablet="{this.width - phoneViewNavigator.width}"
		height.landscapeTablet="{this.height}"
		x.landscapeTablet="270"
		y.landscapeTablet="0"
		height="100%"
		width.portraitTablet="100%"
		x.portraitTablet="0"
		y.portraitTablet="400"
		height.portraitTablet="{this.height - phoneViewNavigator.height}"
 
	/>
	<!--PHONES-->
	<s:ViewNavigator
		width.phone="100%"
		height.phone="100%"
		width.portraitTablet="100%"
		height.portraitTablet="400"
		width.landscapeTablet="270"
		height.landscapeTablet="100%"
		id="phoneViewNavigator"
		backgroundColor="0xffff01"
 
		x="0" y="0"
		firstView="views.ListView"/>

Аппаратная кнопка возврата

Платформа Flex 4.5 по умолчанию обрабатывает клавишу Back Hardware Key на телефонах Android. Он прекрасно работает с классическим приложением ViewNavigatorApplication. В этом случае, поскольку я использую архитектуру оболочки <s: Application>, содержащую два компонента ViewNavigator, нет стека навигации на корневом уровне, и приложение теряется при получении команды Back. Вот код, который отключает классическое поведение. Я добавил его в представление, которое отображает изображение в полном размере.

protected function view1_initializeHandler(event:FlexEvent):void
			{
				// TODO Auto-generated method stub
				systemManager.stage.addEventListener(KeyboardEvent.KEY_DOWN, deviceKeyDownHandler);
				systemManager.stage.addEventListener(KeyboardEvent.KEY_UP, deviceKeyUpHandler);
			}
 
			protected function deviceKeyDownHandler(event:KeyboardEvent):void
			{
				// TODO Auto-generated method stub
				if(event.keyCode == Keyboard.BACK && navigator.length > 1){
					event.preventDefault();
				}
			}
 
			protected function deviceKeyUpHandler(event:KeyboardEvent):void
			{
				// TODO Auto-generated method stub
				if(event.keyCode == Keyboard.BACK && navigator.length > 1){
					navigator.popView();
				}
			}
 
			protected function view1_viewDeactivateHandler(event:ViewNavigatorEvent):void
			{
				// TODO Auto-generated method stub
				systemManager.stage.removeEventListener(KeyboardEvent.KEY_DOWN, deviceKeyDownHandler);
				systemManager.stage.removeEventListener(KeyboardEvent.KEY_UP, deviceKeyUpHandler);
			}

Вы можете скачать исходный код этого приложения и проверить хитрости, представленные в моем коде.

Ссылка на исходный код приложения:  http://riagora.com/pvt_content/android/DynamicLayout.fxp

Я также опубликовал демонстрационное приложение на Android Marketplace:  https://market.android.com/details?id=air.com.riagora.dynamiclayout&feature=search_result.