Опубликован: 01.11.2011 | Доступ: свободный | Студентов: 1424 / 62 | Оценка: 3.84 / 3.44 | Длительность: 15:38:00
Специальности: Программист
Практическая работа 9:

Изменение ориентации экрана (Silverlight)

Аннотация: На данном занятии мы займемся изменением ориентации экрана с портретной в ландшафтную.

Дополнительные материалы к занятию можно скачать здесь.

Пользователи держат телефоны по-разному. При этом в зависимости от того, как они его держат, может меняться ориентация экрана. Вертикальная ориентация, когда высота экрана больше его ширины, является портретной (Portrait). Ландшафтная ориентация (Landscape) - это когда телефон повёрнут и ширина экрана больше его высоты. Вы можете создавать приложения, работающие при любой ориентации экрана, но по умолчанию Windows Phone 7 Silverlight приложения запускаются в портретной ориентации. При этом игры, написанные на XNA, запускаются в ландшафтной ориентации (считается, что игры выглядят лучше на широком экране). В данной статье мы сосредоточимся на Silverlight приложениях и рассмотрим ситуацию, когда ориентация экрана меняется в процессе работы приложения [29].

Главная страница по умолчанию работает только в портретном режиме

После создания нового проекта Windows Phone Silverlight приложения в XAML коде страницы MainPage.xaml можно найти следующий отрывок:

SupportedOrientations="Portrait" Orientation="Portrait"
    

Это значит, что страница декларирует поддержку только портретной ориентации, в которой, собственно, и работает. Свойство SupportedOrientations может принимать одно из следующих значений:

Portrait (по умолчанию)
Landscape
PortraitOrLandscape

Данные значения интуитивно понятны.

Свойство 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>&#32;</Start>
        <End>&#126;</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);
        }
    }
}
    
Листинг .

В результате получаем: