Telerik blogs

Our next XAML Fest post breaks down how to build a user interface like the famous X (Twitter) card.

Welcome to the next article of January XAML Fest! Today, we’re diving into the design and creation of a user interface that’s familiar and beloved by many: the Twitter card. Step by step, you’ll discover how to replicate this card for your very own .NET MAUI app.

The January XAML Fest is a month-long initiative where we showcase various replications of iconic user interfaces. If you’re keen to learn more about this exciting journey, I encourage you to check out the article “Welcome to the January XAML Fest.”

For a comprehensive understanding, here’s an outline of the topics that will structure our article’s explanation:

  • Tips for maximizing the learning experience
  • Understanding the card structure
  • Setting up the main code structure first
  • Preparing with mock data
  • Developing each step in detail

✍️ Tips for Maximizing the Learning Experience

Before we embark on the coding and design journey, it’s essential to make sure you’re fully prepared to make the most of this post. Here are some helpful tips to enhance your experience and increase your productivity as you recreate the Twitter card:

  • Visual reference of the original UI: To begin, we’ll display an image of the original Twitter card, segmented into sections. Each section corresponds to a different aspect of the design we’ll be addressing.

  • Design analysis: Each section will include an image highlighting the specific design element we’re concentrating on. This approach offers a clear and focused examination of each design component.

  • Guided coding sections: In every coding section, keep an eye out for a comment that says, “Insert the code being described in the following section here.” This comment serves as your prompt to insert the forthcoming code explanation right at that point, ensuring a smooth and organized coding experience.

With all these tools at your disposal, you’re now fully equipped to dive into the Twitter card code. Get ready for an exciting journey that offers hands-on experience and in-depth knowledge of .NET MAUI, particularly focusing on XAML for the graphical interface. Let’s embark on this enjoyable adventure—happy coding! 🚀🎨🌟

Understanding the Card Structure

In this section, we’ll delve into the structure of the Twitter card we’re about to create. For this article we will keep a simple card, which only includes a description and an image. The objective is for you to learn to structure the elements correctly.

We’ll break down the card into segments, which we’ll refer to as “steps.” Each step will be distinguished by a unique color and emphasized with stitch-like lines. Let’s take a closer look.

1. Profile image & name, highlighting small profile picture and username.  2. Content, highlighting message and image. 3. Interactions, which include the small icons below the body of the post.

Setting up the Main Code Structure First

Before diving into each step, let’s first set up the primary code structure of the card—think of it as sketching the outline in code. This will serve as the foundation where the content of our forthcoming steps will reside. Let’s begin!

Adding a CollectionView

Remember, we’re building a list! Just as tweets are listed, we’ll prepare a stage to accommodate items, regardless of their content length. To achieve this, we’ll utilize a CollectionView. If you’re unfamiliar with it, a CollectionView is a versatile visual element designed to display lists of data with various layout configurations.

<CollectionView Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" HorizontalScrollBarVisibility="Never"
       ItemsSource="{Binding twitterCardDataList}">

			    <!-- Here goes the code explained in the next explanation -- > 


Main Layout

The Grid arranges its children in rows and columns, allowing for both proportional and absolute sizing. Beyond its impressive performance benefits, it’s also user-friendly. We’ll be leveraging the Grid to structure our card’s visual elements.

To begin, find the comment in the previous code snippet labeled “<!-- Here goes the code explained in the next explanation -->” and insert the following code there:

<!-- Main structure--> 
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto,Auto,Auto" RowSpacing="10" Margin="20" Padding="20">

    <!--Insert the code corresponding to Step 1's explanation here.-- > 
    <!--Insert the code corresponding to Step 2's explanation here.-- > 
    <!--Insert the code corresponding to Step 3's explanation here.-- >


Preparing with Mock Data

For demonstration purposes, we’ll introduce some mock data. This way, you can see your list in action once you finish this guide.

Create your Model: Begin by creating the TwitterCard.cs class, which will serve as your model.

public class TwitterCard
    public string UserName { get; set; } 
    public string UserHandle { get; set; } 
    public string PublicationTime { get; set; } 
    public string TweetDescription { get; set; } 
    public string TweetImageSource { get; set; } 
    public int CommentsCount { get; set; } 
    public int ReTweetCount { get; set; } 
    public int LikesCount { get; set; } 
    public int StatsCount { get; set; } 

Populating Mock Data: Start by creating the TwitterCardViewModel class. Below, I’ve provided data for three cards, but feel free to add as many as you need for your example.

public class TwitterCardViewModel 

    public ObservableCollection<Models.TwitterCard> twitterCardDataList { get; set;}
    public TwitterCardViewModel() 
	    twitterCardDataList = new ObservableCollection<Models.TwitterCard> 
		    new Models.TwitterCard 
			    UserName = "Karol Bass", 
			    UserHandle = "@KarolBass", 
			    PublicationTime = "2s", 
			    TweetDescription = "Take a look at the latest article in the Progress blog. It covers the exciting new features in .NET MAUI and how they can benefit your mobile app development. Don't miss out!", 
			    TweetImageSource = "karolbass", 
			    CommentsCount = 10, 
			    ReTweetCount = 20, 
			    LikesCount = 30, 
			    StatsCount = 40 
		    new Models.TwitterCard 
			    UserName = "Jessy Rose", 
			    UserHandle = "@JessyRose8194", 
			    PublicationTime = "10s", 
			    TweetDescription = "This is the fourth tweet. It's a great day to explore the world of .NET MAUI development. Stay motivated and keep coding!", 
			    TweetImageSource = "jessy", 
			    CommentsCount = 8, 
			    ReTweetCount = 18, 
			    LikesCount = 28, 
			    StatsCount = 38 
		    new Models.TwitterCard 
			    UserName = "Katthy White", 
			    UserHandle = "@KatthyWhite", 
			    PublicationTime = "5m", 
			    TweetDescription = "This is the third tweet. Let's dive deep into the world of cross-platform app development with .NET MAUI. Join me on this exciting journey!", 
			    TweetImageSource = "katty", 
			    CommentsCount = 5, 
			    ReTweetCount = 15, 
			    LikesCount = 25, 
			    StatsCount = 35 

Developing Each Step in Detail 🕵️‍♂️

Our structure is now in place! 💃 Let’s start crafting the visual elements for each step.

Step 1: Profile Image & Name

Step 1: Profile image & name

Place the code detailed in this step at the designated spot in the previous block, marked as “<! -- Insert here the code corresponding to the explanation of Step 1.-->

This step is made up of different elements:

Rounded profile image:

To use the image, we’ll employ the AvatarView from the .NET MAUI Community Toolkit.

1 - Installation: First, make sure to install the toolkit by adding the Community.Toolkit.Maui NuGet package.

Community.Toolkit.Maui NuGet package

2 - Setup in MauiProgram.cs: After adding the NuGet package, navigate to MauiProgram.cs. Right below UseMauiApp(), append:


3 - Namespace Addition: Include the toolkit namespace in your page:


4 - Using AvatarView: Now, you can incorporate the AvatarView into your XAML:

<toolkit:AvatarView Grid.Column="0" Grid.Row="0" Grid.RowSpan="3" 
		    ImageSource="{Binding TweetImageSource}" 

User name, handle & publication time

This section comprises three distinct details: the username, handle and publication timestamp.

While we could use three separate Labels for this, optimizing code and performance is always beneficial. Another alternative is to use FormattedText.

This allows us to apply varied styles within a single label, streamlining the process as demonstrated below:

<Label Grid.Column="1" Grid.Row="0"> 
		    <Span Text="{Binding UserName, StringFormat='{0} '}" FontAttributes="Bold" /> 
		    <Span Text="{Binding UserHandle, StringFormat=' {0} '}" TextColor="#576169" /> 
		    <Span Text="{Binding PublicationTime, StringFormat=' {0}'}" TextColor="#576169" /> 
<!-- Insert the code being described in the following section here -->

✍️ I’ve utilized FormattedText to format the aforementioned text segments. It provides a convenient way to structure strings. For a deeper dive into this topic, visit the docs.

At the end of this step, you will get a result like the following image:

User profile picture, username and handle, timestamp

Step 2: Content

Step 2: Content

In the second step, we’ll add a brief description and a photo. It’s straightforward, as demonstrated in the code snippet below.

<!-- Tweet description --> 
<Label Grid.Column="1" Grid.Row="1" Text="{Binding TweetDescription}"/> 

<!-- Tweet image--> 
<Frame Grid.Column="1" Grid.Row="2" BorderColor="Transparent" HeightRequest="200" HasShadow="False" CornerRadius="12" Padding="0" IsClippedToBounds="True"> 
    <Image Source="{Binding TweetImageSource}" Aspect="AspectFill"/> 

<!-- Insert the code being described in the following section here -->

To achieve rounded corners for the image, I utilized a Frame. Alternatively, you can use .NET MAUI Borders.

Finally, you will get a result like the following image:

After this step, the body of the tweet including text and an image is added

Step 3: Interactions

Step 3: Interactions

🎉 We’ve arrived at the final step! In this phase, we’ll incorporate various icons 🖼️ that symbolize interactions, along with their respective counts. 🔢

We’ll harness the power of FlexLayout, focusing on the JustifyContent property, which will allow you to determine space distribution of child elements along the main axis.

For those unfamiliar with the FlexLayout, think of it as an advanced StackLayout. It not only lines up child elements in horizontal or vertical stacks but also wraps them if there’s an overflow in a single row or column. This provides greater control over layout nuances, from sizing to alignment. For a deeper dive, check out the article “Exploring Layout Options in .NET MAUI.”

Let’s see how to do it in code:

<!-- Interactions--> 
<FlexLayout Grid.Row="3" Grid.Column="1" 
            AlignItems="Center" >

    <!-- Comments --> 
    <Image Source="comment" WidthRequest="15" HeightRequest="15"/> 
    <Label Text="{Binding CommentsCount}" />
    <Image Source="retweet" WidthRequest="15" HeightRequest="15"/> 
    <Label Text="{Binding ReTweetCount}" />
    <Image Source="heart" WidthRequest="15" HeightRequest="15"/> 
    <Label Text="{Binding LikesCount}" />
    <Image Source="stats" WidthRequest="15" HeightRequest="15"/> 
    <Label Text="{Binding StatsCount}" />
    <Image Source="share" WidthRequest="15" HeightRequest="15"/> 


Finally, you will get a result like the following image:

The card now has interaction icons and counts

But there’s more:

Recall at the start of this post, we set everything up, complete with simulated (mock) data to display a list of Tweets. Now, behold the final result!

A feed of tweets

And our X (Twitter) Card is done!

Thanks for reading! 👋 See you next time! 💚💕

About the Author

Leomaris Reyes

Leomaris Reyes is a Software Engineer from the Dominican Republic, with more than 5 years of experience. A Xamarin Certified Mobile Developer, she is also the founder of  Stemelle, an entity that works with software developers, training and mentoring with a main goal of including women in Tech. Leomaris really loves learning new things! 💚💕 You can follow her: Twitter, LinkedIn , AskXammy and Medium.

Related Posts


Comments are disabled in preview mode.