Flutter Demo application linking to BoardGameGeek.Com’s Hot Game List

I’ve built a slightly more interesting application using Flutter.  Using an XML feed from BoardGameGeek’s API, the application displays a list of the current hot games complete with thumbnail images.

Android Screen

Here‘s the code. I used a standard Flutter app template and also added a few packages to the project.

I’ve coded a substantial amount of Windows Presentation Foundation (WPF) and Silverlight code over the years. One of the concerns that often came up was the UI tree …, the more complex it was, the slower the app often was without lots of tricks. Using the new inspector for Flutter apps, I selected one of the images in the UI. Needless to say, there are a few objects created to represent the UI tree. In fact, I had trouble capturing the image for this blog post. :)


Flutter Nesting

I don’t have evidence that this generally will be a performance problem. Maybe with relatively simple mobile applications, a deep rich object based UI hierarchy won’t affect performance as much as it might in a desktop application of reasonable complexity. Regardless, it’s worth considering as you build a UI.

Back to what I built. When a user taps on a board game in the list, I’ve wired the code to call the _showGameItem below. I appreciate that there’s an easy way to navigate to a new page on the stack and show a UI, all within a single function. Of course, I could have split it into multiple builder functions if needed.

To register an event callback for the onTap, I’d tried finding a Widget that exposed it directly. I’m accustomed to elements having events (often bubbling events) that would have exposed something like onTap. However, with the exception of specialized widgets like Buttons for example, it’s not exposed on most Widgets (even those that have UI). So, at the outer layer of the items being shown in the ListView, I used a GestureDetector to capture the tap event:

I would have preferred that the Container to have the event available. Maybe it’s not as pure, but, meh. I’d like to reduce the noise of building a UI and adding yet another layer just to capture an event is a distraction.

Architectural elegance does not always lead to a framework that is easy or friendly.

While I wasn’t really concerned about performance of my application or the possible impact from hitting the BoardGameGeek API a few times, I used application storage to cache a copy of the XML data that’s retrieved from BoardGameGeek just to get some experience with the APIs. Further, I added code to store the next time the file can be updated to the SharedPreferences object instance (to prevent it from being updated too frequently). I liked the simple exception handling in Dart as it’s relatively low impact to handle a specific exception type without caring about the details by using the on clause (just by dropping the catch(e)).

I noticed that the exception handler can specify one or two parameters. The first is always the exception and the second is the stack trace (StackTrace).  I’m not sure why the stack trace isn’t part of the exception object though.

When the file is cached completely and successfully, the Widget state is updated, which triggers an application refresh, which is what happens on lines 29-32.

Had Flutter been an option in the earlier days of Android, it would have been a strong contender in the application building space, especially that it runs on Android and iOS. From reading some of the issues on Github, the general consensus is that the cross-platform Flutter competitor to beat is React Native. In fact, I’m surprised that it has taken Google this long to produce a potentially viable alternative to the Java Android development tools. I’d honestly thought they’d announce something several years ago (I’ve watched Google I/O for many years for the announcement).

If Android devices were upgraded more routinely (as are iOS devices), web technologies such as installed progressive web applications could be a serious contender and alternative for many application types. But, modern Android operating system versions are very slow to roll out (if ever) to the majority of devices.  Over half of Android devices are running Android 6.0 or earlier.

Android Developer Version Distribution

Until the Android OEM ecosystem delivers timely updates to all phones newer than 5 years, solutions like Flutter (and competitors) remain a potentially reasonable way to reach a large variety of devices without needing to update to recent OS releases. However, it may be that the hardware hosting older versions, such as 6.0/Marshmallow and earlier are not capable of adequately executing a modern app built with technology like is used by Flutter.

Continued concerns

I still find the syntax of building a UI to be cumbersome and frustrating for several reasons:

  1. Using code to describe the UI is not effective for me. I can’t as quickly look at a block of code and determine what the UI is likely to be. It’s just too noisy.
  2. I’m constantly frustrated by getting the right number of closing parentheses to match the open parentheses. Using the auto formatting tools of Android Studio for Dart doesn’t make it easier. There are 10 lines that are marking the closing of some block. I’ll add an example below of how messy it starts to look if they’re combined in a way that the auto formatter suggests.
  3. In fact, if it were easy, I’d want to lines to start with the Widget type rather than child: new WidgetName(. But, there’s not an obvious way to format the code that way as the named parameters (child) are needed to provide the widget instance.
  4. Layout is a mess of classes and initialization. The examples on the web site make general sense, but when I’ve tried to innovate on my own and understand how to build other UI patterns, I’ve struggled to find the right combination of Widget classes that represent a desired layout. I imagine that with practice I’d get better, but I also would likely create multiple stateless Widgets to make some of the common patterns I’d expect to use routinely.

Hulk Smash Layout

Does Flutter have a future? Would you want to build an app that you wanted to still be building on 3-4 years from now? As it’s still in Alpha form, I wouldn’t do anything but explore.

Then, there’s Dart. The strength of many development options for mobile and web development is the ability to concentrate on one programming language and have it work on client and server. With Flutter and Dart, if you don’t have a serverless-style architecture in place, you’ll need to use a second programming language. And that may limit its adoption. Of course, developers that work on multiple app platforms today have accepted this is just the price they have to pay, so maybe that’s not a big deal. If you’ve got a development shop that can have developers specialize, then this may be a non-issue entirely. For startups and very small teams, it’s a potential obstacle that must be considered.

 

Notes

If you try the code as I’ve put it on GitHub, you may encounter an error with a codec. This is actually a bug in the Flutter framework and apparently is fixed already and will be available generally at some point in a mainline branch. You’ll just need to rerun it.

Example of Auto Formatting

Note the parentheses on lines 20 and 21. That style causes me to just keep adding closing parentheses until the syntax is correct or the error is different. They’re very difficult to count.

Android Studio

Android Studio is an acquired taste from a theme and style perspective. With a few adjustments, it’s tolerable.

Android Studio Font and Color Settings

I’m not sure why Keywords in the Darcula theme are bright, bolded orange. While keywords are important, they’re unnecessarily vibrant, especially in code blocks describing the UI:

Bright Bold Orange Code Block

I turned off the bold minimally and changed the color of class names as an experiment … it’s better, but not right yet.

Android Studio with custom class name

Geek gift ideas 2016

If you’re looking to buy yourself, I mean someone else some gifts for the upcoming holiday season, here are some items that I’ve found useful or handy around the house. It’s all stuff that I use and would recommend.

KMASHI 400A Peak 14.8V 800mAh Compact Car Jump Starter

It’s around $40. Our cars normally start without issue. Occasionally however, we’ve had a dead battery in an inopportune time or location and needed to call someone for a jump. Now, rather than carrying a giant jump battery in the car, we carry this.

More frequently, I use it to jump start our riding lawn tractor that often has a depleted battery (that I’ve not been able to successfully troubleshoot). I’ve had this for more than a year and used it more than 6 times without any trouble (thankfully, I haven’t needed it more than that). The convenience of it is awesome. It’s so small! Of course, it can also be used as just a USB charger. It charges with an included micro-USB cable.

Tripp Lite 1 Outlet Portable Surge Protector/Suppressor with Timer

Many Li-ion battery chargers for outdoor equipment do not recommend leaving the battery charging at all times. So, I bought this simple single outlet surge protector and timer combination from Tripp Lite.

It costs about $22. I plug a power strip into it and the chargers into the power strip and generally set it to 3 hours if I’ve used the battery powered equipment for very long. At the end of 3 hours, it automatically turns the power off (and to the entire strip) so I don’t need to worry about whether the batteries have charged too long.

Wago 221-413 LEVER-NUTS 3 Conductor Compact Connectors 50 PK

I didn’t know these existed until a year ago. While they’re a luxury item for sure, they make common electrical connections painless (for me at least). I’m sure some of you swear by the old traditional wire-nut. But, after I tried these, I’ll never go back. They make them in a few configurations that are worth looking into.

 

The price varies depending on what type you buy, but they average between 20 to 50 cents each.

I’ve used a lot of the 2 conductor version.

Bike Peddler Take A Look Cycling Eyeglass Mirror

Almost 1500 reviews on Amazon and nearly an average of 5 stars. These things are great. I’ve had one for 3+ years and if you wear glasses and ride a bike and haven’t liked whatever mirror option you currently use, … I love these. They’re simple and effective.

They’re around $12 usually (and you shouldn’t need to pay more than that).

Planet Bike Blinky “3H” 3-Led Rear Bicycle Light with Self Leveling Helmet Mount

PlanetBike Blinky 3H

Bike safety is very important to me. And it should be for you too. This novel little light attaches securely to the rear of your bike helmet and self levels so that it’s always pointing vertically in a reasonable direction. While you could attach it to your bike, there are better and brighter lights available for your bike that I’d recommend instead. Use this as a secondary bike light. It’s lightweight. I don’t notice its there. It’s about $20.

GMS Optical Premium Grade Comfortable Silicone Anti-slip Holder for Glasses, Ear Hook, Eyeglass Temple Tip


If you have sports glasses (I’ve got a pair of prescription Adidas sports glasses for example), you may have situations where you’d like to have a bit more confidence that your glasses aren’t going to hurtle off your face at some point due to unexpected motion, sweat, etc. I’d tried some of the bands that attach to glasses and found them distracting, especially when riding my bike (either too loose or too tight). These simple and inexpensive (around $6) holders give me the confidence to wear my glasses in situations where I was concerned about them falling off my face.

This was especially true while riding my bicycle. When I was looking down while riding (even for a moment to look at the GPS, etc.), I often had the distinct feeling that my glasses were sliding off my face. On hotter days, this was exacerbated by perspiration. No more! While I wouldn’t be brave (or dumb) enough to think that these would hold my glasses on while riding a loop on a modern roller-coaster, they perform well enough for more typical day-to-day sports. As you’ll see from their ratings, I’m not the only person that likes them.

They’re under $6.

Shacke Hidden Travel Belt Wallet w/ RFID Blocker

When traveling internationally, my wife and I always carry our passports on us while out and about (I know that some people leave them in the hotel room). I’ve tried a few different ways to carry my passport over the years, and this is my current favorite discrete carrying option. It’s lightweight and fits well in the front of one of your legs. Occasionally, you’ll notice it, but it’s not distracting. It’s got room for a few more things, but it’s not intended to carry everything; just stuff you don’t frequently need. I put spare cash, a paper map, and often our ATM card inside. Apparently, there were/are gray wallets of this, but unless you have a gray belt, it will show. By the way, this definitely requires that you wear a belt and is about $16.

Canon PowerShot G7 X Mark II (Black)

I’m sure many of you have decided that your phone takes great pictures and that’s all that you need. Fine. I accept that you’re missing out. OK, seriously. Your smart phone probably does take some great pictures. But, some images just can’t be captured by your smart phone. Occasionally, you’ll be able to walk closer to something you want to capture to emulate “zoom”, but often, you’ll find that the picture you captured isn’t the way you remembered it. This is where a nice point-and-shoot + more camera comes into play. I’ll take pictures when I’m on vacation with both this camera and my smart phone. I’m not going to bore you with a long list of features. That’s available on the web.

Here’s why I bought this model:

  • RAW mode + JPEG
  • Touch screen (tap to take a picture)
  • Size / weight
  • Pop-up flash
  • Good battery life (definitely buy spare batteries though)
  • Good bokeh (for a point-and-shoot)
  • 24-100mm zoom. Means I can take adjust zoom.
  • Can attach to my tripod (or mini-tripod) and my Really Right Stuff equipment
  • Easy to adjust f-stop/aperture, etc.

It’s by no means an inexpensive camera. However, I do not foresee any reason I’ll want or need to replace it any time soon. So, for now, I consider it a long term camera.

I would strongly recommend you buy a backup battery, regardless of the camera you choose. I bought some cheaper replacement batteries, not from Canon. I bought the DSTE NB-13L batteries. I bought 2 for 50% of the price of a Canon OEM battery. I’ll warn you, as does the camera when it detects these the first time, that these are not Canon batteries. You’ll need to acknowledge a warning that they are not Original Canon Batteries. They work fine though and I’ve not noticed any significant difference from the standard Canon batteries. They last a reasonable amount of time. Some combinations of extra batteries include an extra charger. Having lost a charger on my last trip to Finland, I was glad I’d brought a spare along.

Also, so that I could use a quick release plate with my Really Right Stuff tripod ballhead, I bought a quick release L plate from Desmond. (I usually buy from Really Right Stuff, but they didn’t have a great inexpensive option for this camera).

The model I bought fits the camera very well and is easy to attach and remove. It does make flipping the screen around more of a challenge, but I accept that limitation and rarely is it an issue (as I can always remove the L plate quickly).

SUNWAYFOTO Table Top Mini Aluminum Tripod T1A10 Tabletop Sunway

I attach my Really Right Stuff BH-25 Ballhead to this little tripod. It works really well.

It’s about $35 and fits nearly anywhere (from a small bag to a large pocket). I find a spot usually on a table, nature (like a rock), etc., snap the camera to it, and take a few pictures. It’s really handy and I take it on all trips where I take a camera other than my smart phone.

AmazonBasics Thermal Laminator


This $22 laminator is great. I had no idea how useful this would be. We bought it initially to protect a bunch of table-top board game cheat sheets we’d made or copied. We print them out on our inkjet on regular paper and then laminate them in a 3 mil thermal laminating pouch. The laminator takes 4-5 minutes to warm up at first so there’s no instant gratification that comes with it’s use. Once it heats though, you can feed sheets in with nearly wild abandon (there’s no reason to wait between sheets). In addition to the cheat sheets, we’ve protected copies of important travel and legal documents, copies of instructions (often that we want to hang near the equipment like our furnace or water filtration system). I’ve made small signs and placards for various events and even cleaning instructions for a few things around our house. The laminating pouches are often found in 3 and 5 mil. The 5 mil sheets are very thick and we don’t use them nearly as often.

I’ve also found that using our paper trimmer for items smaller than a full page works really well (rather than trying to cut with scissors). We’ve got something like this (although not this exact one as I can’t find the model we have). Just buy something with replacement blades in case they dull.

And, I just blogged about it a week ago, the Ecobee ecobee3 thermostat is also on my list.

Next time, I’ll post about some table top board games I’ve enjoyed recently.

HTML 5 Support: iOS 4.1 Browser vs. Windows Phone 7 Browser

Now that the final v1 Windows Phone 7 is available, I performed a few browser tests using http://www.HTML5Test.com (which is a slick and easy way of testing browser support for some upcoming HTML5 features).

Any guesses which is iOS 4.1?

image image

Biggest missing elements from the IE browser on Windows Phone 7:

  • Input element types. The browser won’t be able to provide a keyboard/input panel that is appropriate for the data being requested. For example, a number field that automatically switches to a number only input pad. See here for some examples.
  • Geo-location. Seriously. The phone has a GPS. Why not expose it? (IE9 doesn’t either unfortunately, but that bothers me less).
  • Canvas. IE9 can do it, why not you? There are so many UIs that can be enhanced by use of a canvas,without resorting to server side rendering and other messy hacks.
  • Web applications (cache). Then, we could package a web application into an offline application and use the browser to drive the UI rather than SL/XNA. That’d be a win in my book as it would be easier to build cross platform phone solutions.
  • Session storage and local storage. See previous point. It also makes using cookies less necessary in some scenarios.

It is a better browser than the CRAP in previous versions of the Windows Phone. But, the bar has been set much higher these days. I’m pleased that typical web sites work well, and that it’s reasonably fast. I can even understand why they stopped where they did – as it seemed sufficient for typical browsing needs on the go, especially given the development team obviously had deadlines.

But with technology moving at such a rapid pace and the adoption of HTML5 proceeding regardless of standards, Microsoft must keep up to survive. This phone will get a lot of “hate” if it can’t adequately browse the web in a few years. Developers are tired of building in hacks to support browser X or Y. This is yet another browser that may need to be supported, if adoption rates are reasonable.

image

IE9 Beta 1 scores only a 96.

image

It’s missing Web applications (arrgh), and websockets.

My first Windows Phone 7 Experiment

OK, It doesn’t look like much. It’s not. I was experimenting with some CompositionTarget Rendering and WriteableBitmap stuff on the plane ride out to Mix 2010 on Sunday and created a little animating blue line thing. (I don’t know what to to call it). But it was a work in progress.

I took the code and copied it into a Windows Phone 7 Silverlight application and hit run. It worked right out of the box. (Using the CTP download from here).

image

CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);

The event:

void CompositionTarget_Rendering(object sender, EventArgs e)
{
    int indx = _shapes.Count - 1;
    double littleCircleHeight = littleCircle.ActualHeight;

    while (indx >= 0)
    {
        Sparkle sparkle = _shapes[indx];
        sparkle.Y += sparkle.VY;
        sparkle.X += sparkle.VX;
        if (sparkle.Y - (littleCircleHeight / 2) > _rect.Height)
        {
            _shapes.RemoveAt(indx);
        }
        else
        {
            // grab the cached one
            TranslateTransform t = sparkle.Transform as TranslateTransform;
            t.X = sparkle.X - (littleCircle.ActualWidth / 2);
            t.Y = sparkle.Y - (littleCircleHeight / 2);
            _bitmap.Render(littleCircle, sparkle.Transform);
        }
        indx--;

    }

    int x = _random.Next(_bitmap.PixelWidth);
    int y = 0; 

    Sparkle newsparkle = new Sparkle();
    newsparkle.X = x;
    newsparkle.Y = y;
    newsparkle.VX = _random.NextDouble() + .001;
    newsparkle.VX = (_random.Next(10) > 5 ? newsparkle.VX : newsparkle.VX * -1.0);
    newsparkle.VY = _random.NextDouble() * 5 + 1.0;
    newsparkle.Transform = new TranslateTransform() { Y = newsparkle.Y, X = newsparkle.X };

    _shapes.Add(newsparkle);
    _bitmap.Invalidate();
}

Sizing:

void MainPage_SizeChanged(object sender, SizeChangedEventArgs e)
{
    _bitmap = new WriteableBitmap((int)e.NewSize.Width, (int)e.NewSize.Height);
    _bitmap.Clear(Colors.Black);
    _rect = new Rect(0, 0, e.NewSize.Width, e.NewSize.Height);
    dest.Source = _bitmap;
}

The sparkle class:

public class Sparkle
{
    public double X { get; set; }
    public double Y { get; set; }

    public double VX { get; set; }
    public double VY { get; set; }

    public Transform Transform { get; set; }
}

And it also uses a few functions from the WriteableBitmap extension classes on CodePlex.

It doesn’t perform nearly as well as it does in stand-alone Silverlight – but it’s running in a VM on my laptop, without accelerated graphics ….. I blame my hardware.