Noor Mahdi
Noor Mahdi

Reputation: 3

Creating Xamarin.Forms view that shows paragraph where each sentence is clickable

I have a requirement to create a view on Xamarin.Forms that displays an array of strings in a paragraph. Each sentence should be:
1. Free flowing one after the other on the same line
2. Clickable so that it can be navigated upon click

Also, it is desirable to have such a paragraph justify aligned.

Here is the envisioned wireframe of the requirement. I have highlighted each string with alternating colors to illustrate how the list of strings (sentences) must ingest into a free flowing paragraph

Since I am new to Xamarin and still learning the basics, I need some help in designing this view with appropriate views/controls.

Upvotes: 0

Views: 750

Answers (1)

Lucas Zhang
Lucas Zhang

Reputation: 18861

  1. Free flowing one after the other on the same line
  2. Clickable so that it can be navigated upon click

We could implement them by using Span. Labels expose a FormattedText property that allows the presentation of text with multiple fonts and colors in the same label .

in xaml

<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
   <!-- Place new controls here -->
   <Label
         x:Name="label"
         VerticalTextAlignment="Center"
         HorizontalTextAlignment="Center"
         HorizontalOptions="Center"
         VerticalOptions="CenterAndExpand" />
</StackLayout>

in code behind

var formattedString = new FormattedString();
            
Span span1 = new Span() { Text = "Note that a Span can also respond to any gestures that are added to the span's GestureRecognizers collection .", BackgroundColor = Color.Red,FontSize=20};
span1.GestureRecognizers.Add(new TapGestureRecognizer {NumberOfTapsRequired=1, Command = new Command( ()=> {  // will been invoked when you click it , do some thing you want  } ) });

formattedString.Spans.Add(span1);

Span span2 = new Span() { Text = "Note that a Span can also respond to any gestures that are added to the span's GestureRecognizers collection .", BackgroundColor = Color.Gray, FontSize = 20};
span2.GestureRecognizers.Add(new TapGestureRecognizer { NumberOfTapsRequired = 1, Command = new Command(() => { // will been invoked when you click it , do some thing you want  }) });

formattedString.Spans.Add(span2);

Span span3 = new Span() { Text = "Note that a Span can also respond to any gestures that are added to the span's GestureRecognizers collection .", BackgroundColor = Color.Red, FontSize = 20};
span3.GestureRecognizers.Add(new TapGestureRecognizer { NumberOfTapsRequired = 1, Command = new Command(() => { // will been invoked when you click it , do some thing you want}) });

formattedString.Spans.Add(span3);

label.FormattedText = formattedString;

For more details about Span you could check this docs .

Also, it is desirable to have such a paragraph justify aligned.

We could use Custom Renderer .

Note : JustificationMode is only available after Android 8.0 .

in your android project

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;

using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

using xxx.Droid;

[assembly:ExportRenderer( typeof(Xamarin.Forms.Label),typeof(MyLabelRenderer)) ]

namespace xxx.Droid
{
    public class MyLabelRenderer : LabelRenderer
    {
        public MyLabelRenderer(Context context) : base(context)
        {

        }

        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);

            if(Control!=null)
            {
                if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
                {
                    Control.JustificationMode = Android.Text.JustificationMode.InterWord;
                }
            }

        }
    }
}

enter image description here

Upvotes: 1

Related Questions