Изменение ориентации экрана (Silverlight)
Дополнительные материалы к занятию можно скачать здесь.
Пользователи держат телефоны по-разному. При этом в зависимости от того, как они его держат, может меняться ориентация экрана. Вертикальная ориентация, когда высота экрана больше его ширины, является портретной (Portrait). Ландшафтная ориентация (Landscape) - это когда телефон повёрнут и ширина экрана больше его высоты. Вы можете создавать приложения, работающие при любой ориентации экрана, но по умолчанию Windows Phone 7 Silverlight приложения запускаются в портретной ориентации. При этом игры, написанные на XNA, запускаются в ландшафтной ориентации (считается, что игры выглядят лучше на широком экране). В данной статье мы сосредоточимся на Silverlight приложениях и рассмотрим ситуацию, когда ориентация экрана меняется в процессе работы приложения [29].
Главная страница по умолчанию работает только в портретном режиме
После создания нового проекта Windows Phone Silverlight приложения в XAML коде страницы MainPage.xaml можно найти следующий отрывок:
SupportedOrientations="Portrait" Orientation="Portrait"
Это значит, что страница декларирует поддержку только портретной ориентации, в которой, собственно, и работает. Свойство SupportedOrientations может принимать одно из следующих значений:
Данные значения интуитивно понятны.
Свойство Orientation определяет, в какой ориентации страница запускается. Если Вы хотите, чтобы страница запускалась в ландшафтном режиме, не забудьте добавить этот режим в список поддерживаемых. Свойство Orientation может принимать следующие значения:
Landscape |
LandscapeLeft (телефон опрокинут на левый бок) |
LandscapeRight (телефон опрокинут на правый бок) |
Portrait |
PortraitDown (нормальная вертикальная позиция) |
PortraitUp (телефон перевёрнут) |
Из списка видно, что можно задать не только портретную или ландшафтную ориентацию, но и то, в какую сторону будет повёрнут телефон при той или иной ориентации. Это позволяет очень четко указать с какой ориентацией будет запускаться страница [29].
На данном занятии мы займемся изменением ориентации экрана с портретной в ландшафтную.
По умолчанию программы, написанные на Silverlight для Windows Phone 7, выполняются в портретном режиме, а написанные на XNA - в альбомном. Эти настройки по умолчанию можно изменить.
Создадим новое приложение Silverlight Windows Phone 7. По умолчанию используются свойства: SupportedOrientations="Portrait" Orientation="Portrait":
<phone:PhoneApplicationPage x:Class="WindowsPhoneApplication21.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" shell:SystemTray.IsVisible="True"> <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock x:Name="ApplicationTitle" Text="Портретная ориентация" Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock x:Name="PageTitle" Text="По умолчанию" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}" FontSize="64" /> </StackPanel> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"></Grid> </Grid> </phone:PhoneApplicationPage>
Начальные настройки можно изменить (SupportedOrientations="Landscape"Orientation="Landscape"):
<phone:PhoneApplicationPage x:Class="WindowsPhoneApplication21.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="728" d:DesignHeight="480" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Landscape" Orientation="Landscape" shell:SystemTray.IsVisible="True"> <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock x:Name="ApplicationTitle" Text="Ландшафтная ориентация" Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock x:Name="PageTitle" Text="Изменена" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}" FontSize="64" /> </StackPanel> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"></Grid> </Grid> </phone:PhoneApplicationPage>
(WindowsPhoneApplication21)
То же самое можно проделать и с XNA-приложениями.
Создадим стандартный проект XNA, в котором на экране будет отображаться строка текста. За основу был взят проект из книги Чарльза Петзольда (Программируем Windows Phone 7)
Далее, добавим к проекту шрифт Segoe: Имя проекта(Content) -> Add -> New Item -> Sprite Font -> Segoe
Затем внесем небольшие изменения в xml-файл описания шрифта:
<?xml version="1.0" encoding="utf-8"?> <XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics"> <Asset Type="Graphics:FontDescription"> <FontName>Segoe UI Mono</FontName> <Size>32</Size> <Spacing>0</Spacing> <UseKerning>true</UseKerning> <Style>Bold</Style> <CharacterRegions> <CharacterRegion> <Start> </Start> <End>~</End> </CharacterRegion> </CharacterRegions> </Asset> </XnaContent>
После этого изменим код файла Game1.cs (Чарльз Петзольд):
using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media; namespace WindowsGame9 { public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; string text = "Landscape Orientation"; SpriteFont Segoe; Vector2 textSize; Vector2 textPosition; public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; } protected override void Initialize() { base.Initialize(); } protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); Segoe=this.Content.Load<SpriteFont>("Segoe"); textSize = Segoe.MeasureString(text); } protected override void UnloadContent() { } protected override void Update(GameTime gameTime) { if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); Viewport viewport =this.GraphicsDevice.Viewport; textPosition=new Vector2((viewport.Width-textSize.X)/2,(viewport.Height-textSize.Y)/2); base.Update(gameTime); } protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.White); spriteBatch.Begin(); spriteBatch.DrawString(Segoe,text,textPosition,Color.Red); spriteBatch.End(); base.Draw(gameTime); } } }Листинг .
Запускаем проект:
Для изменения ориентации с альбомной на портретную внесем небольшие изменения в файл Game1.cs:
using System; using System.Collections.Generic; using System.Linq; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.GamerServices; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media; namespace WindowsGame9 { public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; string text = "Portrait"; SpriteFont Segoe; Vector2 textSize; Vector2 textPosition; public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; graphics.SupportedOrientations = DisplayOrientation.Portrait; TargetElapsedTime = TimeSpan.FromTicks(333333); graphics.PreferredBackBufferWidth = 480; graphics.PreferredBackBufferHeight = 800; } protected override void Initialize() { base.Initialize(); } protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); Segoe=this.Content.Load<SpriteFont>("Segoe"); textSize = Segoe.MeasureString(text); } protected override void UnloadContent() { } protected override void Update(GameTime gameTime) { if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); Viewport viewport =this.GraphicsDevice.Viewport; textPosition=new Vector2((viewport.Width-textSize.X)/2,(viewport.Height-textSize.Y)/2); base.Update(gameTime); } protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.White); spriteBatch.Begin(); spriteBatch.DrawString(Segoe,text,textPosition,Color.Red); spriteBatch.End(); base.Draw(gameTime); } } }Листинг .
В результате получаем: