Hanselman.Forms - James Montemagno https://staging.montemagno.com/tag/hanselman-forms/ https://staging.montemagno.com/content/images/2017/08/MonogramIcon_Orange_NoBuffer.png Hanselman.Forms - James Montemagno https://staging.montemagno.com/tag/hanselman-forms/ Hugo -- gohugo.io Tue, 13 Oct 2026 23:21:57 GMT 60 The Beautiful & Complex FlexLayout Comes to Hanselman.Forms https://staging.montemagno.com/flexlayout-image/ 5c821c36b2f3d500bff4c965 Fri, 08 Mar 2019 18:22:00 GMT

Last week I wrote about my new quest to fully optimize and enhance Hanselman.Forms. This involves using the latest and greatest in Xamarin.Forms and Xamarin.Essentials, but it also means spicing up the app with some lovely visuals and design. My first quest was to re-design the podcast section of the mobile app to create a list in grid form of different podcast that Hanselman produces.

So, first things first we should design a card to hold each podcast in. This can be accomplished with a simple Frame with a drop shadow on it:

<Frame
    Padding="0"
    VerticalOptions="Start"
    HasShadow="True">
    <Grid Padding="0">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Image Source="{Binding Art}" Aspect="AspectFill"/>
        <Label Grid.Row="1" Margin="10,0" Text="{Binding Title}"/>
    </Grid>
</Frame>

This simple code results in a pretty nice look for album artwork:

Pod

I will absolutely want to try out the new Visual Frame/CardView enhancements now that Xamarin.Forms 3.6 is out to make sure it also looks great on iOS.

Wrapping Podcasts

Wrapping the multiple podcasts into columns and rows dymanically would be pretty ideal for something like a CollectionView, but it is still in preview. I thought instead that the the FlexLayout would be a great option because it can arrange its children horizontally and vertically in a stack in addition to wrapping items. Here is one of the samples from the documentation:

ExperimentAlignContent2-Large

Taking this concept I was able to combine the FlexLayout with a BindableLayout to make something pretty spectacular:

 <ScrollView>
    <FlexLayout BindableLayout.ItemsSource="{Binding Podcasts}"
           Wrap="Wrap"
           Direction="Row"
           JustifyContent="Start"
           AlignItems="Start"
           AlignContent="Start"
           Padding="8">
        <BindableLayout.ItemTemplate>
            <DataTemplate>
                <Grid Margin="4,4,4,4"
                      FlexLayout.Basis="{OnIdiom Phone='50%', Tablet='33%'}"
                      FlexLayout.AlignSelf="Start">

                   <local:PodcastCardView />

                </Grid>
            </DataTemplate>
        </BindableLayout.ItemTemplate>
    </FlexLayout>
</ScrollView>

It tooke me a long time how to figure out how to space each of the cards correctly and wrap to the next line while still starting on the left hand side. This was accomplished by setting all of the Align properties to Start as well as the JustifyContent. It resulted in a really great Android version:

53674791-420bf280-3c45-11e9-9438-eb608208ce7d

Better yet, when I ran it on UWP or changed the orientation the FlexLayout reacted very nicely:

ezgif.com-resize-1

Seeing this in action I was very content and wrapped up a great week 2 of live streaming updating the app on Twitch.

You can check out the full pull request on GitHub to see how I setup a full mock data source, handled tab transitions, and the final implementation for FlexLayout in the app. Don't forget that I am accepting pull requests and feature requests too on the official GitHub page.

My final take away thoughts are that while the FlexLayout is relatively complicated and has tons of little settings to tweak, it is still extremely powerful and worth dedicating some time to.

]]>
Modernizing Hanselman.Forms: A Customizable Brand Mobile App https://staging.montemagno.com/updating-hanselman-forms-bottom-tabs-bindable-layout/ 5c77172d720b5500bfd5d630 Fri, 01 Mar 2019 16:42:00 GMT

The night before we launched Xamarin.Forms in mid-2014, I was having a conversation with Nat about creating a nice out of the box real world example of a Xamarin.Forms app. We discussed several different app ideas, but we were short on time as it was already 8PM at night. Then I thought perhaps I could create an app for my idol and fellow Chipotle lover Scott Hanselman. Fast-forward 8 hours and several cups of coffee later and Hanselman.Forms was born! It was very simple with an about page, Twitter feed, and blog rss reader with a simple Master Detail setup:

Hanselman1

Scott liked it so much that he wrote an awesome blog about it.

Over the years it morphed to include an Android Wear and Apple Watch app that was featured at the .NET Conf keynote.

Over time I added more features such as circle images and podcast playback:

hanseman

The project has received several updates including migrating to the latest versions of Xamarin.Forms, .NET Standard, Xamarin.Essentials, and all of the NuGet packages that I use. However, it has never really gotten a great modern user interface make over. So, in 2019 I want to change that and I am kicking off the Hanselman.Forms modernization project!

This project will be on going on my Twitch stream where I will morphing this app into a beautiful modern design mobile app. I plan on using some of the latest features in Xamarin.Forms 4.0, adding offline sync, enhancing the audio player, changing the navigation, and who knows what else. I want it to be fun and interactive where we can work on the project together and make it a spectacular reference app. Last week I kicked off the first round of improvements, and here is what I accomplished.

Week 1 Accomplishments

Last week on my Twitch livestream I created a huge list of issues that can be worked on by anyone! I decided to start by creating a new vnext branch that we can work off together. I decided to start off by implementing new TabbedPage navigation with lovely bottom tabs on Android:

bottomtabs

After that it was off to re-factor all of the social links on the home page. In the past I had put a bunch of images with tap gesture recognizers on them.

<StackLayout Orientation="Horizontal"
         HorizontalOptions="CenterAndExpand"
         Spacing="10">

    <Image x:Name="twitter" Source="twitter.png"/>
    <Image x:Name="facebook" Source="facebook.png"/>
    <Image x:Name="instagram" Source="instagram.png"/>
</StackLayout>
twitter.GestureRecognizers.Add(new TapGestureRecognizer()
{
    Command = new Command(async () =>
    {
        //try to launch twitter or tweetbot app, else launch browser
        var launch = DependencyService.Get<ILaunchTwitter>();
        if (launch == null || !launch.OpenUserName("shanselman"))
            await Browser.OpenAsync("http://m.twitter.com/shanselman");
    })
});

facebook.GestureRecognizers.Add(new TapGestureRecognizer()
{
    Command = new Command(async () => await Browser.OpenAsync("https://m.facebook.com/shanselman"))
});

instagram.GestureRecognizers.Add(new TapGestureRecognizer()
{
    Command = new Command(async () => await Browser.OpenAsync("https://www.instagram.com/shanselman"))
});

This was very hacky code and didn't fit in with MVVM at all. Luckily we now have Bindable Layouts in Xamarin.Forms. So now, the XAML is all nice and organized and there is NO code in the code behind as it is all in the View Model :)

<StackLayout Orientation="Horizontal"
                     HorizontalOptions="CenterAndExpand"
                     Spacing="10" BindableLayout.ItemsSource="{Binding SocialItems}">
      <BindableLayout.ItemTemplate>
          <DataTemplate>
            <Image Source="{Binding Icon}">
              <Image.GestureRecognizers>
                    <TapGestureRecognizer
                            Command="{Binding OpenUrlCommand}" />
              </Image.GestureRecognizers>
            </Image>
          </DataTemplate>
      </BindableLayout.ItemTemplate>
</StackLayout>

I am thinking that I can probably get rid of the tap gesture recognizer and use the new ImageButton with a transparent background :)

Get Involved

I would love if you would come hang out with me as I code every Friday at 2PM Pacific live on Twitch so we can rev on this together. I am also interested in feature requests, design ideas, and reviewing pull requests live while I stream. Head over to the GitHub page to give it a star and submit or comment on some issues.

]]>