Greenpeace nieuws in Modern UI

Met de opkomst van de nieuwe Windows 8 en de bijbehorende Modern UI (vroeger Metro) komen er steeds meer apps in de Windows Store. In deze blog post willen ik laten zien hoe we een RSS reader kunnen maken voor het nieuwe Modern UI Windows 8.

Het concept

Om te beginnen wil ik een concept hebben. Nu is het maken van een RSS reader vrij recht toe recht aan. Een app die een RSS feed inleest en dat afbeeld in items binnen categorieën. Dit sluit allemaal mooi aan bij de template van Visual Studio 2012. Na een brainstormsessie van ongeveer 10 seconden besluit ik een nieuws reader te maken voor het nieuws van Greenpeace, wat gevonden kan worden op www.greanpeace.nl. Ik wil al een heel tijdje iets doen voor een goed doel en waarom niet nu. Ik ben niet van plan een uitgebreide app nu te maken, maar wellicht komt dat nog in de toekomst.

Project

Ik start met de template van Visual Studio 2012. Ik kies de template door New Project > Windows Store > Grid App (XAML). Dit geeft mij een template waarbij we werken met drie onderdelen. Het nieuws item, de categorie (een groep met een collectie van items) en de collectie van categorieën (collectie van groepen). Deze drie onderdelen zijn al verwerkt in de template.

We krijgen een klant en klare Windows 8 app tot onze beschikking.

Wat we hier boven zien is het project. De standaard onderdelen die we kennen uit de Windows Phone 7 projecten zijn onder andere de properties, app.xaml en de pagina’s, hier de andere xaml bestanden. Er worden ook wat nieuwe folders toegevoegd. De Assets map bevat de grafische elementen die worden gebruikt in de app. Deze gaan we aanpassen naar onze eigen smaak. Hierin staan de logo’s en het splash screen onder andere.

In de Common map staan de onderdelen van onder andere standaard elementen die worden gebruikt in de app. Dit maakt het wel makkelijker om stukken opmaak te hergebruiken. Dit worden onder andere gedaan voor de elementen in de lijst die we zien als we de app starten. De grote van de listitems en de opmaak daarvan wordt beschreven in de StandardStyles.xaml. In deze map staan ook wat nieuwe objecten beschreven zoals de RichTextColumns en de LayoutAwarePage. Deze laatste wordt onder andere gebruikt om te zorgen dat als we de app op een Tablet draaien en we kantelen de tablet, dat de app ook mee draait en de juiste layout toont.

In de DataModel map vinden we een bestand, namelijk de SampleDataSource.cs. Dit bestand bevat verschillende classes. Een abstracte class genaamd SampleDataCommon. Deze bevat wat basis properties en wat overrides. Niets bijzonders, maar deze wordt wel gebruikt als basis voor de andere classes die zich ook in hetzelfde bestand bevinden.

  • SampleDataItem is de class voor de Item wat bij ons dadelijk het nieuwsbericht is.
  • SampleDataGroup is de class voor de collectie van Items, ofwel de categorieën of groep
  • SampleDataSource is een class die niet de Common extend, maar alleen staand is. Deze class wordt gebruikt om de data te laden. Deze gaan we aanpassen.

Allereerst wil ik dat ‘Sample’ weg hebben. Ik doe gewoon een search and replace op Sample waardoor ik DataItem, DataGroup, DataSource en DataCommon overhoud. Dat vind ik wat netter staan. Even een Build draaien om te checken of ik niets gebroken heb door alles te vervangen. Nope, dus we kunnen door.

Feed Syndication

Om te beginnen haal ik eerst de sample data weg. Dit staat in de class DataSource (voorheen SampleDataSource). In de constructor van de class worden de groepen aangemaakt met de voorbeeld items. Deze hebben we niet meer nodig, want die gaan we vervangen met de echt data van de RSS feed.

Voor het laden van de RSS ga ik de SyndicationFeed gebruiken. Ik die dit wel in een aparte methode, zodat het niet direct in de constructor zit. Dat vind ik netter. Ik maak daarvoor een nieuwe methode aan genaamd GetFeedsAsync(). Ik gebruik daarvoor de onderstaande code.

public DataSource()
{
    // starten van het laden van de feed
    GetFeedsAsync();
}

/// <summary>
/// Get the feed
/// </summary>
/// <returns></returns>
public async Task GetFeedsAsync()
{
    // waar komt de RSS vandaan
    Uri blogUri = new Uri("http://www.greenpeace.nl/Templates/Planet3/Handlers/RssHandler.ashx?type=news&epslanguage=nl", UriKind.Absolute);

    // aanmaken van een nieuwe Syndication Client
    SyndicationClient client = new SyndicationClient();
    // Laden van de feed, asynchroon
    SyndicationFeed feed = await client.RetrieveFeedAsync(blogUri);

    // voor elk item die we terug krijgen
    foreach (SyndicationItem item in feed.Items)
    {
        // eerste de groepen maken, tijdelijke list
        List<DataGroup> groups = new List<DataGroup>();

        // als we geen groepen kunnen vinden
        if (groups.Count > 0)
        {
            // voor elke categorie die we kunnen vinden in de items, voegen we die toe als groep
            foreach (SyndicationCategory cat in item.Categories)
            {
                // groep aanmaken, als de groep al bestaat, dan die gebruiken
                DataGroup group = this.AllGroups.FirstOrDefault(i => i.UniqueId == cat.NodeValue);

                // als de groep niet bestaan, nieuwe maken
                if (group == null)
                {
                    // nieuwe groep aanmaken
                    group = new DataGroup(cat.NodeValue, cat.NodeValue, feed.Subtitle.Text.ToString(), "", cat.NodeValue);
                    // de groep toevoegen aan de collectie van groepen
                    this.AllGroups.Add(group);
                }

                // groep toevoegen aan de tijdelijke list, zodat we die kunnen gebruiken om de items aan toe te voegen
                groups.Add(group);
            }
        }
        else
        {
            // de groep ophalen als we die al hebben
            DataGroup group = this.AllGroups.FirstOrDefault();
            // als we nog geen groep hebben
            if (group == null)
            {
                // de nieuwe groep aanmaken
                group = new DataGroup(Guid.NewGuid().ToString(), feed.Title.Text, feed.Subtitle.Text, "", feed.Subtitle.Text);
                // de groep toevoegen aan de collectie van groepen
                this.AllGroups.Add(group);
            }
            // de groep toevoegen aan de lijst
            groups.Add(group);
        }

        // de content vormgeven
        string content = item.Summary.Text.ToString();
        // weghalen van de HTML tags, als deze er zijn
        content = Regex.Unescape(Regex.Replace(content, "<.*?>", string.Empty));

        // voor elke groep die in de categorieen voorkomen in de item voegen we de item toe
        foreach (DataGroup gr in groups)
        {
            // nieuwe item toevoegen aan de groep
            // de groepen zijn by reference toegoegd aan de lijst, dus de groep in de lijst en in de AllGroups zijn hetzelfde
            gr.Items.Add(
                new DataItem(
                Guid.NewGuid().ToString(),
                item.Title.Text.ToString(),
                item.Title.Text.ToString(),
                "",
                content,
                content,
                gr)
            );
        }
    }
}

In de bovenstaande code wordt de feed geladen en worden per items die terug komen de groepen aangemaakt waaraan de bijbehorende items worden toegevoegd. Helaas geeft de feed ons niet het hele bericht terug, maar alleen een samenvatting. Ook komt er geen image mee met de feed, dus heel grafisch ziet onze app er niet uit.

Afwerking

Om de app verder af te maken, kan je per item het artikel downloaden. Deze kan je door middel van dezelfde Regex code strippen van de HTML tags. Ook kan je zoeken naar afbeeldingen in het bericht zodat je die kan toevoegen als image bij het aanmaken van de DataItem. Dat zorgt er dan voor dat de items in de lijst een afbeelding laten zien. Dat ga ik hier niet behandelen, dat mag je zelf doen :).

Natuurlijk moet de app nog een passend uiterlijk krijgen. Je kan de Assets aanpassen zodat deze de grafische elementen laten zien die je wilt in de app. Ik ga de achtergrond aanpassen naar een lichte kleur. Ook zet ik in de Package.appxmanifest het thema op Dark, zodat ik donkere letters krijg op mijn lichte achtergrond. In de StandardStyles.xaml verander ik de kleur en de achtergrond. Ik kan bijvoorbeeld bij de LayoutRootStyle de property Background aanpassen naar de onderstaande code.

<Style x:Key="LayoutRootStyle" TargetType="Panel">
    <Setter Property="Background">
        <Setter.Value>
            <ImageBrush ImageSource="Assets/BackgroundImage.jpg" />
        </Setter.Value>
    </Setter>
    <Setter Property="ChildrenTransitions">
        <Setter.Value>
            <TransitionCollection>
                <EntranceThemeTransition/>
            </TransitionCollection>
        </Setter.Value>
    </Setter>
</Style>

Hier heb ik een ImageBrush toegevoegd die de achtergrond veranderd naar een JPG image. Ook moet ik zeker zijn dat we de Dark Theme kunnen aanroepen. Dat moet ik toevoegen in de App.xaml.

<Application
    x:Class="Greenpeace_Nieuws_Reader.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Greenpeace_Nieuws_Reader"
    xmlns:localData="using:Greenpeace_Nieuws_Reader.Data"
    RequestedTheme="Light">

Zie hier de RequestedTheme property die ik toegevoegd heb. Deze zet ik op Light, zodat de theme automatisch de tekst donker zal maken.

Afsluiting

De app is bijna af. Wat opmaak, het downloaden van images en de complete artikelen en dan kan hij de Store in. Let op dat je hem ook een keer laadt in de emulator om screenshots te maken als je hem submit naar de Store. Zodra deze af ik zal ik wat screenshots plaatsen. Succes!

  1 comment for “Greenpeace nieuws in Modern UI

  1. 22 december 2012 at 22:23

    Thanks Bob! Kan ik binnenkort de ad reader app voor Windows 8 maken:D

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Verplichte velden zijn gemarkeerd met *

Zoals de meeste websites gebruiken we cookies om een meer persoonlijke en snelle service te bieden.

Wij gebruiken cookies zodat onze website meer efficiënt kan functioneren, om de prestaties te verbeteren en, eventueel, om op maat reclame van onze partners aan te bieden. Als u doorgaat gaan we ervan uit dat u akkoord gaat alle cookies te krijgen van onze website.

To accept cookies please Click To Continue