I wanted to know if there is no way other than custom rendering to arrange the ends of the texts in xamarinforms?
Because the modification does not support Android 7 and below.
Thanks to those who respond!
This code is related to my CustomRendering , which in Android 7, my app crashes:
[assembly: ExportRenderer(typeof(CustomLabel), typeof(CustomLabelRender))]
namespace Liko.Droid
{
public class CustomLabelRender : LabelRenderer
{
public CustomLabelRender(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.JustificationMode = JustificationMode.InterWord;
}
}
}
}
On Android 7.0, it do not support JustificationMode
. JustificationMode
is added in API level 26.
https://developer.android.com/reference/android/R.attr#justificationMode
The customrenderer could justify text in Android 7.0 with ViewRenderer.
Custom control:
public class JustifiedLabel : Label
{
}
Csutom renderer:
[assembly: ExportRenderer(typeof(JustifiedLabel), typeof(JustifiedLabelRenderer))]
namespace Test.Droid { public class JustifiedLabelRenderer : ViewRenderer { public JustifiedLabelRenderer(Context context) : base(context) {
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
{
base.OnElementChanged(e);
//if we have a new forms element, we want to update text with font style (as specified in forms-pcl) on native control
if (e.NewElement != null)
{
if (Control == null)
{
//register webview as native control
var webView = new Android.Webkit.WebView(Context);
webView.VerticalScrollBarEnabled = false;
webView.HorizontalScrollBarEnabled = false;
webView.LoadData("<html><body> </body></html>", "text/html; charset=utf-8", "utf-8");
SetNativeControl(webView);
}
//if we have a new forms element, we want to update text with font style (as specified in forms-pcl) on native control
UpdateTextOnControl();
}
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
//if there is change in text or font-style, trigger update to redraw control
if (e.PropertyName == nameof(Label.Text)
|| e.PropertyName == nameof(Label.FontFamily)
|| e.PropertyName == nameof(Label.FontSize)
|| e.PropertyName == nameof(Label.TextColor)
|| e.PropertyName == nameof(Label.FontAttributes))
{
UpdateTextOnControl();
}
}
void UpdateTextOnControl()
{
var webView = Control as Android.Webkit.WebView;
var formsLabel = Element as Label;
// create css style from font-style as specified
var cssStyle = $"margin: 0px; padding: 0px; text-align: justify; color: {ToHexColor(formsLabel.TextColor)}; background-color: {ToHexColor(formsLabel.BackgroundColor)}; font-family: {formsLabel.FontFamily}; font-size: {formsLabel.FontSize}; font-weight: {formsLabel.FontAttributes}";
// apply that to text
var strData =
$"<html><body style=\"{cssStyle}\">{formsLabel?.Text}</body></html>";
// and, refresh webview
webView.LoadData(strData, "text/html; charset=utf-8", "utf-8");
webView.Reload();
}
// helper method to convert forms-color to css-color
string ToHexColor(Color color)
{
var red = (int)(color.R * 255);
var green = (int)(color.G * 255);
var blue = (int)(color.B * 255);
var alpha = (int)(color.A * 255);
var hex = $"#{red:X2}{green:X2}{blue:X2}";
return hex;
}
}
Usage:
<StackLayout Margin="20">
<Entry x:Name="InputEntry" />
<Label
Margin="0,10,0,0"
BackgroundColor="Navy"
FontSize="15"
HorizontalOptions="CenterAndExpand"
Text="Normal Text Label"
TextColor="White" />
<Label
FontAttributes="Bold"
FontSize="20"
Text="{Binding Text, Source={x:Reference InputEntry}}" />
<Label
Margin="0,10,0,0"
BackgroundColor="Navy"
FontSize="15"
HorizontalOptions="CenterAndExpand"
Text="Justified Text Label"
TextColor="White" />
<local:JustifiedLabel
BackgroundColor="Yellow"
FontAttributes="Bold"
FontSize="20"
HorizontalOptions="FillAndExpand"
Text="{Binding Text, Source={x:Reference InputEntry}}"
TextColor="Green"
VerticalOptions="FillAndExpand" />
</StackLayout>
Screenshot:
Updated:
public class JustifiedLabelRenderer : ViewRenderer
{
Context _context;
Android.Webkit.WebView webView;
public JustifiedLabelRenderer(Context context) : base(context)
{
_context = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
{
base.OnElementChanged(e);
//if we have a new forms element, we want to update text with font style (as specified in forms-pcl) on native control
if (e.NewElement != null)
{
if (Control == null)
{
//register webview as native control
webView = new Android.Webkit.WebView(_context);
webView.VerticalScrollBarEnabled = false;
webView.HorizontalScrollBarEnabled = false;
var formsLabel = Element as Label;
// create css style from font-style as specified
var cssStyle = $"margin: 0px; padding: 0px; text-align: justify; color: {ToHexColor(formsLabel.TextColor)}; background-color: {ToHexColor(formsLabel.BackgroundColor)}; font-family: {formsLabel.FontFamily}; font-size: {formsLabel.FontSize}; font-weight: {formsLabel.FontAttributes}";
// apply that to text
var strData = $"<html><body style=\"{cssStyle}\">{formsLabel?.Text}</body></html>";
webView.LoadDataWithBaseURL("", strData, "text/html; charset=utf-8", "utf-8", "");
SetNativeControl(webView);
}
}
string ToHexColor(Color color)
{
var red = (int)(color.R * 255);
var green = (int)(color.G * 255);
var blue = (int)(color.B * 255);
var alpha = (int)(color.A * 255);
var hex = $"#{red:X2}{green:X2}{blue:X2}";
return hex;
}
}
xaml:
<local:JustifiedLabel
BackgroundColor="Yellow"
FontAttributes="Bold"
FontSize="20"
WidthRequest="500"
HeightRequest="500"
HorizontalOptions="FillAndExpand"
Text="I wanted to know if there is no way other than custom rendering to arrange the ends of the texts in xamarinforms? Because the modification does not support Android 7 and below. Thanks to those who respond! This code is related to my CustomRendering , which in Android 7, my app crashes:"
TextColor="Green"
VerticalOptions="FillAndExpand" />
Screenshot: