• This repository has been archived on 31/Oct/2020
  • Stars
    star
    249
  • Rank 162,171 (Top 4 %)
  • Language
    C#
  • License
    MIT License
  • Created about 5 years ago
  • Updated almost 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Spiritual successor to EasyLoading, turn any layout element into an individual state-aware element.

Moved to the Xamarin Community Toolkit

This project has been archived, as it has been integrated into the Xamarin Community Toolkit. From there it can be maintained better by an evergrowing community of awesome contributors. The NuGet package itself is also deprecated from this point onwards. Please migrate over to the Xamarin Community Toolkit version when available.


Xamarin.Forms.StateSquid

A collection of attached properties that let you specify state views for any of your existing layouts.

Build Status

Why StateSquid?

Displaying items when your app is in a specific state is a common pattern throughout any mobile app. People create loading views to overlay on an entire screen or maybe just a subsection of your screen needs an individual loader. When there's no data to display we create empty state views or when something goes wrong we need to build an error state view. By implementing the StateLayout's attached properties you can turn any layout element like a Grid or StackLayout into an individual state-aware element! StateSquid will take care of when to display which view.

Getting started

The project is up on NuGet at the following URL:

https://www.nuget.org/packages/Xamarin.Forms.StateSquid

Install this package into your shared project. There is no need to install it in your platform specific projects. After that you're good to go! Simply add the namespace declaration and the new StateLayout related attached properties should be available to you!

Adding a simple loading state

Each layout that you make state-aware using the StateLayout attached properties contains a collection of StateView objects. These can be used as templates for the different states supported by StateLayout. Whenever the CurrentState is set to a value that matches the State property of one of the StateViews its contents will be displayed instead of the main content.

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
   xmlns:state="clr-namespace:Xamarin.Forms.StateSquid;assembly=Xamarin.Forms.StateSquid" 
   x:Class="SampleApp.MainPage">

   <Grid state:StateLayout.CurrentState="{Binding CurrentState}">
      <state:StateLayout.StateViews>
         <state:StateView StateKey="Loading">
            <Grid BackgroundColor="White">
               <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
                  <ActivityIndicator Color="#1abc9c" IsRunning="{Binding CurrentState, Converter={StaticResource StateToBooleanConverter}, ConverterParameter={x:Static state:State.Loading}}" />
                  <Label Text="Loading..." HorizontalOptions="Center" />
               </StackLayout>
            </Grid>
         </state:StateView>
      </state:StateLayout.StateViews>      
  
     ...
     
  </Grid>
  
</ContentPage>

The State property supports one of the following values:

  • Loading
  • Saving
  • Success
  • Error
  • Empty
  • Custom
  • None (this will show the default view).

Using custom states

Besides the built-in state StateSquid also supports a Custom state. By setting State="Custom" and CustomStateKey="[yourvalue]" you can create custom states beyond the built-in ones. You can use the CurrentCustomStateKey on your root StateLayout element to databind a variable that indicates when to show one of your custom states.

 <StackLayout Padding="10" state:StateLayout.CurrentState="{Binding CurrentState}" state:StateLayout.CurrentCustomStateKey="{Binding CustomState}" BackgroundColor="#f0f1f2">
   <state:StateLayout.StateViews>
      <state:StateView StateKey="Custom" CustomStateKey="ThisIsCustomHi">
         <Label Text="Hi, I'm a custom state!" VerticalOptions="Center" VerticalTextAlignment="Center" HorizontalOptions="Center" HorizontalTextAlignment="Center"  />
      </state:StateView>
      <state:StateView StateKey="Custom" CustomStateKey="ThisIsCustomToo">
         <Label Text="Hi, I'm a custom state too!" VerticalOptions="Center" VerticalTextAlignment="Center" HorizontalOptions="Center" HorizontalTextAlignment="Center"  />
      </state:StateView>
   </state:StateLayout.StateViews>
   <Label Text="This is the normal state." VerticalOptions="Center" VerticalTextAlignment="Center" HorizontalOptions="Center" HorizontalTextAlignment="Center" />
</StackLayout>

Skeleton loading

Skeleton screens in different shapes and sizes are found everywhere across the web and apps — anywhere us humans are forced to wait. They are usually perceived as being shorter in duration when compared against a blank screen and a spinner.

To mitigate focus on the loading process, versus the actual content that is loading, Luke Wroblewski introduced a new design pattern — the skeleton screen. In his own words, they are "essentially a blank version of a page into which information is gradually loaded." These visual placeholders were shown by Wroblewski to be light grey boxes that appeared instantly in areas where content had not yet completed loading.

StateSquid supports adding a skeleton loader like appearance using a SkeletonView. This view is automatically animated to show a slight blinking state animation. You can see it in action in the image below. Simply add it to your loading template and size it accordingly. You can even use CornerRadius to make rounded variations of it.

Repeating a template multiple times

When loading multiple items of the same type it could be benificial if we can simply repeat a piece of XAML without having to copy paste it multiple times. This is where RepeatCount comes into play. By defining a RepeatTemplate we can repeat the same bit of XAML but only define it once. A sample of this process can be seen here.

<StackLayout state:StateLayout.CurrentState="{Binding CurrentState}" Grid.Row="0">
     <state:StateLayout.StateViews>
        <state:StateView StateKey="Loading" RepeatCount="3">
            <state:StateView.RepeatTemplate>
                <DataTemplate>
                    <Grid Padding="20" HeightRequest="120">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="24" />
                            <RowDefinition Height="20" />
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="14" />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <state:SkeletonView CornerRadius="6" Grid.Row="0" Grid.ColumnSpan="2" HeightRequest="20" BackgroundColor="#cccccc" WidthRequest="120" />
                        <state:SkeletonView CornerRadius="6" Grid.Row="1" Grid.ColumnSpan="3" HeightRequest="20" BackgroundColor="#cccccc" WidthRequest="200" />
                        <BoxView Grid.Row="2" Grid.ColumnSpan="3" HeightRequest="1" BackgroundColor="#cccccc" Margin="0,8" />
                        <Label Grid.Row="3" Grid.Column="0" HorizontalOptions="Center" Text="TOTAL ARTICLES" FontSize="10" TextColor="Gray" />
                        <Label Grid.Row="3" Grid.Column="1" HorizontalOptions="Center" Text="PRICE" FontSize="10" TextColor="Gray" />
                        <Label Grid.Row="3" Grid.Column="2" HorizontalOptions="Center" Text="BOXES" FontSize="10" TextColor="Gray" />
                        <state:SkeletonView CornerRadius="6" Grid.Row="4" Grid.Column="0" HeightRequest="20" BackgroundColor="#cccccc" HorizontalOptions="Fill" />
                        <state:SkeletonView CornerRadius="6" Grid.Row="4" Grid.Column="1" HeightRequest="20" BackgroundColor="#cccccc" HorizontalOptions="Fill" />
                        <state:SkeletonView CornerRadius="6" Grid.Row="4" Grid.Column="2" HeightRequest="20" BackgroundColor="#cccccc" HorizontalOptions="Fill" />
                    </Grid>
                </DataTemplate>
            </state:StateView.RepeatTemplate>
        </state:StateView>
    </state:StateLayout.StateViews>
<StackLayout>

This code results in the following UI, where the template is repeated three times:

Property reference

Your imagination is the only limit to what you can do. You can use this control to recreate your layout and make a skeleton loader our of it. Or you can just use a simple Label to indicate that your application is in a specific state. The following parts are what make this thing tick:

Property Available on What it does Extra info
CurrentState StateLayout Defines the current state of the layout and which template to show. Loading, Saving, Success, Error, Empty, None, Custom
CurrentCustomStateKey StateLayout Pair this with State="Custom" on a StateView to add custom states.
StateViews StateLayout A list of StateView objects that contains a template per State.
CustomStateKey StateView Used to identify a StateView when using State="Custom"
RepeatCount StateView Repeats the specific StateView by a given amount. Ideal to use to show a list of multiple items for e.g. a skeleton loader.
RepeatTemplate StateView Defines the DataTemplate that gets repeated when using RepeatCount.
State StateView Used to identify a StateView to be shown for a specific State.

More Repositories

1

Xamarin.Forms.PancakeView

An extended ContentView for Xamarin.Forms with rounded corners, borders, shadows and more!
C#
862
star
2

Xamarin.Forms.DebugRainbows

The package you didn't even know you needed!
C#
414
star
3

KickassUI.Spotify

A Xamarin.Forms version of the Spotify app to prove you can create goodlooking UI with Xamarin.Forms
C#
240
star
4

Mynt

An Azure Functions-based crypto currency trading bot; featuring 10 exchanges, 25 indicators, custom strategy support, backtester and more
C#
236
star
5

Xamarin.Forms.EasyLoading

Loading views made easy!
C#
121
star
6

KickassUI.ParallaxCarousel

A Xamarin.Forms version of a parallax carousel to prove you can create goodlooking UI with Xamarin.Forms
C#
115
star
7

MVP

Unofficial app to help MVPs manage their community activities
C#
111
star
8

KickassUI.Runkeeper

A Xamarin.Forms version of the Runkeeper app to prove you can create goodlooking UI with Xamarin.Forms
C#
105
star
9

KickassUI.Twitter

A Xamarin.Forms version of the Twitter app to prove you can create goodlooking UI with Xamarin.Forms
C#
87
star
10

iBakePancakes

A fancy UI sample for an app providing pancake recipes
C#
77
star
11

KickassUI.Chameleon

A Xamarin.Forms based encyclopedia UI example
C#
72
star
12

Plugin.Maui.DebugRainbows

C#
72
star
13

KickassUI.Banking

A Xamarin.Forms version of a banking app concept, showing off how to use a base page
C#
64
star
14

KickassUI.Traveler

A Xamarin.Forms based travel app UI sample
C#
59
star
15

Coffeeffee

Implementation of a coffee shopping UI using Xamarin.Forms
C#
52
star
16

FocusOnXamarin

NET Conf: Focus on Xamarin sample
C#
51
star
17

KickassUI.FancyTutorial

A simple Xamarin.Forms tutorial screen
C#
48
star
18

KickassUI.InSpace

C#
43
star
19

MSALSample

A quick sample on how to implement MSAL in your app.
C#
19
star
20

YouTubeEmbed

Sample on how you can embed YouTube content in your Xamarin Forms app.
C#
15
star
21

Xamarin.Neumorphism

C#
13
star
22

SkiaGitHubGraph

A GitHub-type contribution graph using SkiaSharp
C#
12
star
23

AnimationsSample

A few animation samples using Xamarin.Forms
C#
9
star
24

PancAPI

A simple json file with pancake data :D
6
star
25

BasePageRevisited

C#
3
star
26

PropPlaques

A bunch of STL files that can be used to print small plaques for geeky/nerdy props
2
star
27

thewissenio

Personal website, yay!
SCSS
1
star
28

presentations

1
star