2017-12-31 146 views
0

Ich habe diesen benutzerdefinierten Renderer, bei dem ich die Größe des Textes so anpassen möchte, dass er nur für die Umrandung der Schaltfläche passt, wenn der Textbegrenzungsrahmen größer ist als der der Schaltfläche.Wie zeichnet man nur den Hintergrund einer Xamarin.Forms-Schaltfläche?

Was ich versuche ist, den Text "von Hand" über den Hintergrund der Schaltfläche zu zeichnen, ohne dass die Schaltfläche selbst den Text zeichnen kann.

Ist dies möglich, ohne eine andere Art von Ansicht zu verwenden, um eine Schaltfläche zu fälschen?

Kann ich irgendwie den FontSize-Eigenschaften-Setter vom Renderer abfangen, sodass ich seinen Wert in einem Ivar speichern kann, während Null an die Schaltfläche übergeben wird, damit der Text nicht gezeichnet wird?

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); 
     } 
    } 
} 
+0

Warum Sie den Text, um die Größe benötigen haben? Könnten Sie bitte etwas mehr ausarbeiten? –

+0

@ YorkShen-MSFT für Geräte mit höherer skalierter Dichte und kleinem Bildschirm erscheint der Text auf der Schaltfläche außermittig und abgeschnitten. – rraallvv

+0

@ YorkShen-MSFT aktualisiert die Frage mit, wie ich Änderungen im Wert von 'FontSize' in' OnElementPropertyChanged' festgestellt habe – rraallvv

Antwort

1

, wie ich Änderungen im Wert von Fontsize in OnElementPropertyChanged

Wenn Sie Ihre Xamarin.Forms.ButtonFontSize Eigenschaft ändern zu erkennen angetan hat, diese Änderung wie dies in der OnElementPropertyChanged Methode ermitteln könnte:

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!"); 
} 

Aktualisierung:

Holen Sie sich das ButtonFontSize Wert:

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); 
} 
+0

Gibt es eine Möglichkeit, den alten Wert zu erhalten? 'PropertyChangedEventArgs' hat nur' PropertyName'. Vielen Dank. – rraallvv

+0

@rraallvv, ich habe meine Antwort aktualisiert. –

Verwandte Themen