Nano Hash - криптовалюты, майнинг, программирование

Windows Phone 8.1 Загрузка изображений с удаленных URL-адресов Заполнитель

Я возился с некоторыми разработками для Windows Phone, так как я новичок в этом, исходя из фона Android.

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

У меня пока следующее:

XAML:

<Page
    x:Class="CatFactsPics.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CatFactsPics"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid x:Name="LayoutRoot">

        <Grid.ChildrenTransitions>
            <TransitionCollection>
                <EntranceThemeTransition/>
            </TransitionCollection>
        </Grid.ChildrenTransitions>

        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- TitlePanel -->
        <StackPanel Grid.Row="0" Margin="24,17,0,28">
            <TextBlock Text="My Application" Style="{ThemeResource TitleTextBlockStyle}" Typography.Capitals="SmallCaps"/>
            <TextBlock Text="page title" Margin="0,12,0,0" Style="{ThemeResource HeaderTextBlockStyle}"/>
        </StackPanel>

        <!--TODO: Content should be placed within the following grid-->
        <Grid Grid.Row="1" x:Name="ContentRoot">
            <Image HorizontalAlignment="Center" Stretch="UniformToFill" VerticalAlignment="Center" x:Name="KittyPic" Tapped="KittyPic_Tapped"/>
            <Button HorizontalAlignment="Center" VerticalAlignment="Bottom" x:Name="newPic" Click="newPic_Click" >New Kitty</Button>
        </Grid>
    </Grid>
</Page>

и в page.cs:

...
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            this.navigationHelper.OnNavigatedTo(e);

            Uri myUri = new Uri("http://thecatapi.com/api/images/get?format=src&type=jpg", UriKind.Absolute);
            KittyPic.Source = new BitmapImage(myUri);
        }
...
        private void newPic_Click(object sender, RoutedEventArgs e)
        {
            Uri myUri = new Uri("http://thecatapi.com/api/images/get?format=src&type=jpg", UriKind.Absolute);
            BitmapImage bmi = new BitmapImage();
            bmi.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
            bmi.UriSource = myUri;
            KittyPic.Source = bmi;
        }

У меня есть пара вопросов:

1) это правильный способ ведения дел? В Android я бы попытался сделать что-то асинхронно, чтобы избежать остановки потока пользовательского интерфейса. При этом у меня, похоже, нет никаких проблем с тем, что есть сейчас. Я не знаком с тем, как работает Windows, и не нашел никаких ресурсов, дающих какие-либо объяснения или советы по этому поводу.

2) Существует задержка в отображении нового изображения, вызывающая короткий (несколько секунд) период, когда изображение становится черным, прежде чем новое изображение появится снова. Есть ли способ настроить его так, чтобы либо старое изображение оставалось до тех пор, пока новое физически не будет готово к отображению, либо, в качестве альтернативы, отображало «загружающееся» изображение заполнителя, пока новое не сможет его заменить.

Любые другие советы или подсказки о том, как что-то делать, были бы замечательными, спасибо.


Ответы:


1

1) С вашим текущим кодом вы не блокируете поток пользовательского интерфейса, поскольку да, вы устанавливаете URI в потоке пользовательского интерфейса, но фактическая загрузка изображения выполняется в другом потоке автоматически. (Для ручной загрузки изображений, строк и т. д. вы, вероятно, будете использовать async/await, чтобы избежать блокировка потока пользовательского интерфейса).

2) Изображение становится черным, потому что вы меняете ImageSource до загрузки нового изображения. Как вы упомянули, есть несколько способов справиться с этим. Общим для большинства из них является то, что вы захотите использовать события ImageOpened и ImageFailed в элементе управления Image, которые срабатывают всякий раз, когда изображение загружается (или возникает ошибка, например, нет подключения к Интернету). Вот пример отображения полосы загрузки во время загрузки, которая просто скрывает/показывает ход загрузки:

В файле page.xaml:

<Grid Grid.Row="1" x:Name="ContentRoot">
    <Image x:Name="KittyPic" Tapped="KittyPic_Tapped" ImageOpened="KittyPic_ImageOpened" ImageFailed="KittyPic_ImageFailed" />
    <StackPanel x:Name="LoadingPanel" VerticalAlignment="Center">
        <ProgressBar IsIndeterminate="True" IsEnabled="True" />
        <TextBlock Text="Loading image..." HorizontalAlignment="Center" />
    </StackPanel>
</Grid>

И в файле page.xaml.cs

private void KittyPic_Tapped(object sender, TappedRoutedEventArgs e)
{
    LoadingPanel.Visibility = Visibility.Visible;
    Uri myUri = new Uri("http://thecatapi.com/api/images/get?format=src&type=jpg", UriKind.Absolute);
    BitmapImage bmi = new BitmapImage();
    bmi.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
    bmi.UriSource = myUri;
    KittyPic.Source = bmi;
}

private void KittyPic_ImageOpened(object sender, RoutedEventArgs e)
{
    LoadingPanel.Visibility = Visibility.Collapsed;
}

private async void KittyPic_ImageFailed(object sender, ExceptionRoutedEventArgs e)
{
    LoadingPanel.Visibility = Visibility.Collapsed;
    await new MessageDialog("Failed to load the image").ShowAsync();
}

Вместо TextBlock и ProgressBar вы, конечно, можете показывать все, что хотите, или, например, переключаться между двумя изображениями, чтобы продолжать показывать старое.

Для других советов, я думаю, когда вы привыкнете к основам, стоит взглянуть на привязки данных, которые очень полезны и эффективны. Также ознакомьтесь с этой статьей о паттерне MVVM.

24.04.2014
  • Спасибо за отличный ответ. Гораздо более подробно, на что я даже надеялся. У Microsoft есть отличная документация и советы, мне просто очень трудно ее найти. Думаю, что их макет мог бы сделать с некоторым улучшением 26.04.2014
  • Я только что провел несколько часов, пытаясь следовать этому руководству по шаблону MVVM, и большая часть из него бесполезна для WP8.1, поскольку пространства имен изменились, например, локальные настройки приложения работают совершенно по-другому и просто меняют пространство имен на Windows.Storage .Current.LocalSettings недостаточно. хотя я понял суть 17.05.2014

  • 2

    1) это правильный способ ведения дел?

    Нет, это не так. Вам определенно следует принять шаблон MVVM и отделить свою бизнес-логику от вашего представления, то есть вы не должны создавать растровые изображения или запрашивать/назначать URL-адреса таких удаленных изображений в коде вашего представления. Вы должны делать такие вещи в своей ViewModel и привязывать их к своему представлению.

    Таким образом, в вашем случае будет свойство Uri (или строка, в которой вы назначите удаленный URL-адрес) в вашей ViewModel (которая реализует INotifyPropertyChanged), а затем в своем представлении вы будете привязывать его следующим образом:

    <!--TODO: Content should be placed within the following grid-->
        <Grid Grid.Row="1" x:Name="ContentRoot">
             <BitmapImage UriSource="{Binding BackGroundImage}" CreateOptions="BackgroundCreation" />
            <Button HorizontalAlignment="Center" VerticalAlignment="Bottom" x:Name="newPic" Click="newPic_Click" >New Kitty</Button>
        </Grid>
    

    Всякий раз, когда вы устанавливаете свойство BackGroundImage, вы будете вызывать вызываемое событие; RaisePropertyChanged("BackGroundImage") -> Это классический подход MVVM.

    Так что ваше представление будет знать о том, что BackGroundImage изменено, и загрузит его автоматически. (Но обратите внимание, что если вы просто предоставите строку для этого BackGroundImage, вам придется использовать конвертер, конвертер строки в Uri, так как он принимает Uri только для удаленных изображений)

    2) "... Есть ли способ настроить его так, чтобы либо старое изображение оставалось до тех пор, пока новое физически не будет готово к отображению, либо, в качестве альтернативы, отображало "загружающееся" изображение-заполнитель, пока новое не сможет его заменить".

    Я предлагаю перейти к отображению «загружаемого» изображения. Я столкнулся с той же проблемой, что и вы здесь, и мой обходной путь для этого заключался в том, чтобы вставить загружаемое изображение и установить его значение непрозрачности на 0,1 - вместе с фактическим изображением. Когда вы переключаетесь между удаленными URL-адресами, когда предыдущее изображение исчезает, появляется непрозрачное загрузочное изображение, а когда загружается следующее фактическое изображение, загрузочное изображение не отображается, потому что новое изображение перезаписывает его.

    28.04.2014
  • Спасибо за советы. MVVM кажется важным в приложениях clr, я буду работать с учебником, предложенным Йоханом выше, когда у меня будет время 28.04.2014
  • Я не понимаю, почему это должно иметь большое значение, поскольку шаблон MVVM прекрасно решает множество проблем для приложений Windows Phone. 28.04.2014
  • Вы неправильно поняли, что я сказал, я полностью согласен, поэтому это имеет большое значение для приложений для Windows Phone, исходящих от Android, где MVVM не является чем-то, что вы видите так сильно. Посмотрев на него, я полностью согласен с его ценностью для разработки Windows, поэтому я намерен работать с учебником на MSDN. Другая платформа, разные способы ведения дел, и в этом есть смысл 28.04.2014
  • Новые материалы

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

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

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

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..