问题
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;
}
}
}
}
回答1:
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:
回答2:
In general you may use Effects, but that won't make any significant difference.
The code above is not Xamarin.Forms, but rather Xamarin.Android. As such to code it well you must learn Android as Xamarin.Android is just mapped general Android Java APIs to .NET APIs.
Speaking of your problem you need to check for the version of Android before executing the code that is problematic. But your general problem is that you don't know Android, so you'll have many problems like this unless you learn it.
来源:https://stackoverflow.com/questions/65173507/justify-text-without-custom-render