Reputation: 2933
I have this custom renderer where I want to resize the text to fit the button's bounding rect only if the text bounding box is greater than the button's.
What I'm trying to do is to draw the text "by hand" on top of the button's background without allowing the button itself to draw its text.
Is this possible without using a different type of view to fake a button?
Can I intercept somehow the FontSize property setter from the renderer, so I can store its value in some ivar while passing zero to the button so it won't draw the text?
public class AutoTextSizeButtonRenderer : ButtonRenderer
{
private float fontSize = 0;
private static float EPSILON = 0.1f;
public AutoTextSizeButtonRenderer(Context context) : base(context)
{
SetWillNotDraw(false);
}
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
Button button = Element as Button;
if (Math.Abs(button.FontSize - 1) > EPSILON && Math.Abs(button.FontSize - fontSize) > EPSILON) {
fontSize = (float)button.FontSize;
button.FontSize = 1;
}
//Draw(new Canvas());
}
public override void Draw(Canvas canvas)
{
base.Draw(canvas);
Button button = Element as Button;
string text = button.Text;
if (text != null)
{
TextPaint paint = new TextPaint();
//paint.SetTypeface(Typeface.DefaultBold);
paint.AntiAlias = true;
Rect bounds = new Rect();
Paint.FontMetrics metrics = null;
DisplayMetrics displayMetrics = new DisplayMetrics();
Display.GetMetrics(displayMetrics);
float scaledDensity = displayMetrics.ScaledDensity;
float textSize = fontSize;
while(textSize >= 0)
{
paint.TextSize = scaledDensity * textSize;
paint.GetTextBounds(text, 0, text.Length, bounds);
metrics = paint.GetFontMetrics();
if (bounds.Width() < MeasuredWidth && (metrics.Bottom - metrics.Top) < MeasuredHeight) {
break;
}
textSize--;
}
paint.Color = button.TextColor.ToAndroid();
canvas.DrawText(
text,
0.5f * MeasuredWidth - bounds.Left - 0.5f * bounds.Width(),
0.5f * MeasuredHeight - metrics.Ascent - 0.5f * (metrics.Bottom - metrics.Top),
paint);
}
}
}
Upvotes: 0
Views: 192
Reputation: 9084
how I did to detect changes in the value of FontSize in OnElementPropertyChanged
When you change your Xamarin.Forms.Button
FontSize
property, you could detect this change in the OnElementPropertyChanged
method like this :
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == Xamarin.Forms.Button.FontSizeProperty.PropertyName)
System.Diagnostics.Debug.WriteLine("FontSizeProperty has changed!");
}
Get the Button
FontSize
value :
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == Xamarin.Forms.Button.FontSizeProperty.PropertyName)
System.Diagnostics.Debug.WriteLine("FontSizeProperty has changed!");
System.Diagnostics.Debug.WriteLine("Element.FontSize == " + Element.FontSize);
}
Upvotes: 1