Статьи

31 день Windows 8 | День № 3: Заставка

Эта статья является Днем № 3 в серии под названием  31 Дней Windows 8 . Каждая из статей этой серии будет опубликована как для  HTML5 / JS, так  и для  XAML / C # . Вы можете найти дополнительные ресурсы, загрузки и исходный код на нашем  сайте .

advertisementsample

Сегодня мы поговорим о небольшой, но очень важной части жизненного цикла приложения: заставке. Некоторые из вас поначалу воспримут это как глупую тему, но на самом деле это невероятно важно с точки зрения взаимодействия с пользователем.

Скажем, в качестве примера, что ваше приложение подключается к Интернету для сбора некоторых данных. Может быть, вы приложение погоды. Каждый раз, когда пользователь запускает ваше приложение, ему нужны данные с точностью до секунды. Вы знаете, что на сбор данных, соответствующих изображений и их сборку на странице вашего приложения обычно уходит 2-3 секунды.

То, что мы видим во многих приложениях, это то, что приложение загружается пустым, почти на испорченную страницу, только для того, чтобы быть заполненным через 2-3 секунды. Используя заставку и ее события, мы можем «расширить» возможности заставки, чтобы наши пользователи не видели наше приложение, пока мы не готовы к этому. Пара лишних секунд, глядя на заставку,  всегда предпочтительнее, чем открытие испорченного приложения.

Итак, в этой статье мы будем определять, где было расположено исходное изображение заставки, и заменять его изображением заставки «заполнитель», пока наше приложение не будет заполнено соответствующим образом.

Если вы помните из нашей статьи о первом дне, изображение на заставке всегда 620 х 300 пикселей. Для этого примера мы предоставим вам две версии этого изображения. Первый — оригинальный красный:

Заставка

Кроме того, мы создали идентичную версию изображения в фиолетовом цвете, чтобы мы могли видеть разницу, когда они меняются местами, и в то же время иметь возможность заметить, смещается ли вообще положение текста.

SplashScreenPlaceholder

Добавьте эти два изображения в папку «Активы» в новом «пустом» проекте. Если вы запустите этот проект после замены изображений, вы должны увидеть красное изображение за секунду или две до того, как ваши приложения загрузятся на темный экран.

Наш следующий шаг — создать отдельную страницу, чтобы перейти к иллюзии заставки. Добавьте новую пустую страницу в свой проект:

AddNewBlankSplashPage

Мы назвали страницу Splash.xaml, но вы можете назвать ее как угодно для вашего приложения. После добавления нашего фиолетового изображения на страницу, вот как выглядит источник:

<Page
x:Class="Day3_SplashScreen.Splash"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Day3_SplashScreen"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Grid Background="#464646">
        <Image x:Name="SplashImage" Source="Assets/SplashScreenPlaceholder.png" Width="620" Height="300" />
    </Grid>
</Page>

Как видите, очень просто. Просто добавил изображение на нашу страницу. Следующим шагом является изменение нашего файла App.xaml.cs, чтобы сначала направить пользователя на эту страницу.

Разработчики, создающие простые приложения, могут даже не открывать этот файл, но именно здесь происходит большая часть магии. App.xaml.cs содержит наши методы запуска и другие функции системного уровня, такие как управление состоянием между сеансами приложения. В этом случае мы ищем метод OnLaunched (). Я удалил все посторонние комментарии, которые есть по умолчанию, но вы специально ищете место, где он пытается перемещаться (typeof (MainPage), args.Arguments).

protected override void OnLaunched(LaunchActivatedEventArgs args)
        {
            Frame rootFrame = Window.Current.Content as Frame;
            if (rootFrame == null)
            {
                rootFrame = new Frame();
                if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
                {
                    //TODO: Load state from previously suspended application
                }
                Window.Current.Content = rootFrame;
            }
            if (rootFrame.Content == null)
            {
                if (!rootFrame.Navigate(typeof(Splash), args.Arguments))
                {
                    throw new Exception("Failed to create initial page");
                }
            }
            Window.Current.Activate();
        }

По умолчанию наше приложение пытается перейти к MainPage.xaml, и мы хотим изменить это. Замените ссылку на MainPage ссылкой на Splash, как я делал в моем примере выше. Сначала пользователь переместится на нашу страницу Splash.xaml, где мы сможем выполнить загрузку, необходимую для выполнения.

Вперед и запустите ваше приложение. Когда мы помещаем наше фиолетовое изображение в сетку, мы стремимся к тому, чтобы его жизнь была полностью центрирована на экране пользователя. Вы должны увидеть, что фиолетовый ящик отлично заменяет красный. Вот краткое видео для иллюстрации, если вы просто читаете, а не пишете код (почему вы не пишете код?)

Так мы закончили? Даже не близко. Пока что у нас есть дешевый и простой способ продлить заставку. Существует гораздо более сложная модель, если вам интересно.

Допустим, вы ищете нечто большее, чем просто увеличение длины, которую показывает заставка. Возможно, вы хотите узнать, КОГДА был закрыт экран-заставка, или конкретное место, где изображение экрана-заставки отображалось на экране? Вы можете сделать это благодаря   объекту SplashScreen, который   предоставляет нам пространство имен Windows.ApplicationModel.Activation .

Сначала давайте снова посмотрим на наш файл App.xaml.cs. Мы собираемся изменить первоначальный вызов нашей страницы Splash.xaml, передав объект SplashScreen нашему конструктору страниц. Для упрощения мы вырвали весь код по умолчанию из метода OnLaunched и заменили его следующим. Мы добавили комментарии, чтобы объяснить каждую строку кода:

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
    //First we want to check to see if the application was already running.

    if (args.PreviousExecutionState != ApplicationExecutionState.Running)
    {

        //If it wasn't, then we want to check to see if it was terminated the last time it was run,
        //which we will pass on to our Splash page.

        bool loadState = (args.PreviousExecutionState == ApplicationExecutionState.Terminated);

        //Create a new Splash page object passing the SplashScreen object to the constructor.

        Splash splashPage = new Splash(args.SplashScreen, loadState);

        //Set our current app's content = the new Splash page.

        Window.Current.Content = splashPage;
    }
    Window.Current.Activate();
}

Теперь, когда мы передали эту информацию, нам нужно изменить способ написания нашего конструктора Splash.xaml.cs, чтобы мы могли получать эти значения, когда они поступают. Откройте файл Splash.xaml.cs и перепишите свой  открытый метод Splash (),  чтобы он выглядел так:

public SplashScreen splashScreen;
public Rect splashImage;
public Splash(SplashScreen splashscreen, bool loadState)
{
    this.InitializeComponent();
    splashScreen = splashscreen;
    splashImage = splashScreen.ImageLocation;
}

Как вы можете видеть, так как мы изменили способ вызова нашей страницы Splash в нашем файле App.xaml.cs, нам также нужен наш метод конструктора, чтобы соответствовать той же сигнатуре, получая объект SplashScreen и логическое значение. Значение LoadState передается на нашу страницу, чтобы сообщить нам, загружаемся ли мы из ранее завершенного состояния или нет. (Помните, что мы установили это значение в примере App.xaml.cs выше.)

Наш следующий шаг — подписаться на обработчик событий, когда SplashScreen закрывается. Мы делаем это, как и любой другой обработчик событий. Добавьте эту строку в конец созданного нами нового конструктора:

splashScreen.Dismissed += new TypedEventHandler<SplashScreen, Object>(splashScreen_Dismissed);

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

void splashScreen_Dismissed(SplashScreen sender, object args)
{
}

Наконец, нам нужно определить, где на экране была расположена заставка. В этой части примера мы будем использовать расположение заставки, чтобы определить, где разместить рекламное изображение под ним, пока загружается остальная часть нашего приложения.

Во-первых, вот рекламное изображение, которое мы используем. (Не стесняйтесь использовать это в своих приложениях.) :)

advertisementsample

Добавьте это в свой проект, а затем обновите файл Splash.xaml, чтобы он выглядел следующим образом:

<Canvas Background="#464646">
    <Image x:Name="SplashScreenImage"
          Source="Assets/SplashScreenPlaceholder.png"
            Width="620"
            Height="300"
            Visibility="Collapsed"/>
    <Image x:Name="AdvertisementImage"
            Source="Assets/advertisementsample.png"
            Width="620"
            Height="100"
            Visibility="Collapsed"/>
</Canvas>

Как вы можете видеть в XAML выше, я удалил элемент управления Grid и заменил его на Canvas. На самом деле это было только для того, чтобы показать, что я не использую какие-либо свойства центрирования по умолчанию в Grid, и вместо этого мне нужно быть абсолютно точным в размещении моего изображения.

Вернитесь к своему файлу Splash.xaml.cs и добавьте еще одну строку в ваш конструктор (вызов PositionAdvertise), чтобы он выглядел как эта окончательная версия:

public SplashScreen splashScreen;
public Rect splashImage;
public Splash(SplashScreen splashscreen, bool loadState)
{
    this.InitializeComponent();
    splashScreen = splashscreen;
    splashImage = splashScreen.ImageLocation;
    splashScreen.Dismissed += new TypedEventHandler<SplashScreen, Object>(splashScreen_Dismissed);
    PositionAdvertisement();
}
void splashScreen_Dismissed(SplashScreen sender, object args)
{
}

Наконец, нам нужно создать метод PositionAdvertise и переместить наши изображения в соответствующие места, прежде чем изменять их свойства Visibility на Visible. Получив доступ к свойствам X, Y, Высота и Ширина объекта SplashScreen.ImageLocation.

private void PositionAdvertisement()
{
    SplashScreenImage.SetValue(Canvas.TopProperty, splashImage.Y);
    SplashScreenImage.SetValue(Canvas.LeftProperty, splashImage.X);
    SplashScreenImage.Height = splashImage.Height;
    SplashScreenImage.Width = splashImage.Width;
    SplashScreenImage.Visibility = Visibility.Visible;
    AdvertisementImage.SetValue(Canvas.TopProperty, (splashImage.Y + splashImage.Height + 100));
     AdvertisementImage.SetValue(Canvas.LeftProperty, splashImage.X);
    AdvertisementImage.Visibility = Visibility.Visible;
}

Как вы можете видеть, мы помещаем SplashScreenImage в ту же позицию, что и изображение заставки по умолчанию, которое является частью приложения. Затем мы устанавливаем рекламу на 100 пикселей ниже, чем SplashScreenImage. Итак, ваш окончательный файл Splash.xaml должен выглядеть так (нажмите, чтобы увеличить):

образ

Вот и все!

Короче говоря, заставка может стать вашим другом. Это временная завеса, скрывающая ваше приложение до тех пор, пока оно не будет готово, а также место для размещения некоторой рекламы в бесплатных приложениях. Это очень ценная часть приложений, и мы определенно думаем, что вы должны рассмотреть возможность использования в каждом приложении.

Чтобы загрузить весь пример решения из этой статьи, вы можете скачать его здесь:

downloadXAML

Завтра мы собираемся сосредоточиться на некоторых новых общих элементах управления, доступных нам при разработке XAML для Windows 8. Мы рассмотрим такие вещи, как GridView, FlipView и другие. Но это завтра. Увидимся позже!