Metro Nuggets

Bitesized tidbits for building Modern (Metro) apps.

How to Display Ads/Review Prompts/Whatever Inline in Lists

A while back, I read a really interesting article on the best way to approach prompting your user to leave a review for your app, it’s a really good read, so I do encourage you to take a moment and give it the once over. The TL;DR version of it, though, is basically: don’t push a prompt up to yours users to leave a review, don’t do anything that shoves this kind of thing in the user’s face, be it ads, reviews or whatever. The suggested solution is to display your review prompts inline with the rest of your display data (this assumes you have that).

So how do we go about doing that on Windows Phone/Windows? Actually, it’s rather simple (sorry Silverlight, this is not for you).

The Solution

The solution is to use a combination of interfaces, DataTemplateSelectors and some MagicCode. So let’s begin.

First off, let’s look at the files you’ll need:

IListType.cs
This is the interface that your objects (ViewModels, models, whatever) need to implement.

namespace ScottIsAFool.Windows.Core.ViewModel
{
    public interface IListType
    {
        ListType ListType { get; }
    }
}

ListType.cs
This is the type of object that those objects are wanting to identify as.

namespace ScottIsAFool.Windows.Core.ViewModel
{
    public enum ListType
    {
        Normal,
        Review,
        Ad
    }
}

ListTypeExtensions.cs
This is the MagicCode that will insert a specific item type into your list

using System;
using System.Collections.Generic;
using System.Linq;
using ScottIsAFool.Windows.Core.ViewModel;

namespace ScottIsAFool.Windows.Core.Extensions
{
    public static class ListTypeExtensions
    {
        public static List AddEveryOften(this IEnumerable collectionList, int everyOften, int maxNumberToShow, IListType itemToAdd, int startAt = 0, bool addAsFirstItem = false)
        {
            var list = collectionList.ToList();
            if (list == null || !list.Any())
            {
                return new List();
            }

            var itemsAdded = 0;
            var numberOfItemsToAdd = Math.Floor((decimal)list.Count / everyOften);

            for (var i = 0; i  0 ? i : i + 1;
                var addAt = addAsFirstItem && i == 0 ? startAt : (multiplyValue * everyOften) + startAt;
                if (addAt > list.Count)
                {
                    break;
                }

                list.Insert(addAt, itemToAdd);

                itemsAdded++;
                if (itemsAdded == maxNumberToShow)
                {
                    break;
                }
            }

            return list;
        }
    }
}

ListTypeDataTemplateSelector.cs
This is used in your listview so you can customise the DataTemplate for each type.

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using ScottIsAFool.Windows.Core.ViewModel;

namespace ScottIsAFool.Windows.Data
{
    public class ItemTypeDataTemplateSelector : DataTemplateSelector
    {
        public DataTemplate NormalTemplate { get; set; }
        public DataTemplate AdTemplate { get; set; }
        public DataTemplate ReviewTemplate { get; set; }

        protected override DataTemplate SelectTemplateCore(object item)
        {
            var listType = item as IListType;
            if (listType == null)
            {
                return base.SelectTemplateCore(item);
            }

            switch (listType.ListType)
            {
                case ListType.Normal:
                    return NormalTemplate;
                case ListType.Ad:
                    return AdTemplate;
                case ListType.Review:
                    return ReviewTemplate;
                default:
                    return base.SelectTemplateCore(item);
            }
        }
    }
}

So using these files, easy? Yup. I actually used this in my Vid.me app, Viddi (store/github), so I shall pull examples from the code of that app for this blog post.

In Viddi, each item in my list is wrapped in a ViewModel, so in this case, it made sense for my ViewModel to implement IListType and set the ListType property accordingly. In this app, I didn’t actually want to show any ads, I just wanted to show a review prompt (under my own conditions, when you display it is entirely up to you). So I have a ReviewViewModel that also sets the ListType property accordingly. Now this should all be fairly straightforward, and I can hear you asking “when are you getting to the good [MagicCode] stuff?”

So let’s now assume we have our different types, we want to insert them into the list we already have. Now, again, you might have your own criteria about how often you want these things to appear, you may want them to only appear once per list, or every x times; fortunately, the extension method I provide has you covered either way.

                    IEnumerable videoList;

                    if (IncludeReviewsInFeed() && !allVideos.IsNullOrEmpty())
                    {
                        videoList = allVideos.AddEveryOften(10, 2, ReviewService.Current.ReviewViewModel);
                    }
                    else
                    {
                        videoList = allVideos;
                    }

In that code, you can see that I’m checking whether I want to actually display the review prompt, and if I do, then I want to insert it for every 10 items (starting at 0, by default), but to only show a maximum of two prompts. This extension method can be used to insert the items starting at a particular point, or to add one at the start of the list, etc, it’s very flexible.

So you’ve got your code in, the lists are now showing as having your items, plus the review/ad/whatever items in them, now we come to some xaml (it’s only a little, don’t worry).

            

Each of those DataTemplates could be set further in xaml, rather than as Resources, but that’s for you to decide. Then from your list, it’s as simple as setting the DataTemplateSelector property

ItemTemplateSelector="{StaticResource VideoTemplateSelector}"

So there you have it, a simple way to have your ads/review prompts/whatever inline within your lists, rather than in your users’ faces.

All the files required for this are in a gist https://gist.github.com/ScottIsAFool/9f81ac757e0625de1574 and as mentioned, a working app can be seen with Viddi https://github.com/scottisafool/viddi

SL

Advertisements

One response to “How to Display Ads/Review Prompts/Whatever Inline in Lists

  1. r2d2rigo August 19, 2015 at 23:19

    Very nice article, Scott! I dabbled with an implementation of the same article some time ago and I found that inlining ads is a bit more difficult since they usually (at least the AdDuplex one) complain when they are out of the screen or partially occluded by other interface element. With the help of Matt Lacey I had to implement two tweaks:
    – Make sure the list is using virtualization, so items (in this case data templates containing the ad control) are active only when they are on screen.
    – Modify the ListView template so the vertical scrollbar is drawn behind the items. This will only look if your items have enough horizontal margins though.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: