2015-07-14 13 views
5

Ho provato a implementare il componente RadialProgress (https://components.xamarin.com/view/radialprogress) sulla mia app. Sono riuscito a farlo sullo schermo e cambiare il colore di avanzamento ma non riesco a trovare un modo per cambiare il colore interno del cerchio.Xamarin - Radial Progress Component Edizione

L'oggetto RadialProgressView ha un campo BackgroundTintMode che accetta un DuffPorter.Mode ma ogni volta che provo a impostare la modalità tinta in background l'app interrompe con questo messaggio (Messaggio = "nessun metodo con name = 'setBackgroundTintMode' signature = '(Landroid/grafica/PorterDuff $ modalità;?!))

c'è anche un modo per fare quello che voglio

Grazie

+0

hai una soluzione per questo? – SARATH

+0

Sfortunatamente, non ho fatto Sarath. Non ho ancora provato il suggerimento di Mina, anche se così quando lo farò ti farò sapere. – Zez3

risposta

8

Sì, si può fare. Anche se non in modo molto semplice o addirittura gestibile.

In primo luogo, cerchiamo di scavare un po 'in codice di disegno RadialProgressView s' (come esposto da Xamarin Studio Assemblea Browser):

protected override void OnDraw(Canvas canvas) 
    { 
     // ... there's more stuff here, but you get the idea 
     canvas.DrawCircle(this.bgCx, this.bgCy, this.radius, this.bgCirclePaint); 
     canvas.DrawCircle(this.bgCx, this.bgCy, this.innerLineRadius, this.bgBorderPaint); 
     canvas.DrawText(this.valueText, this.textX, this.textY, this.textPaint); 
    } 

Notiamo alcuni colori qui, come bgCirclePaint e bgBorderPaint. Se siamo in grado di cambiare il valore di queste variabili, saremo in grado di cambiare il colore con cui viene dipinto ProgressView.

Il problema è che RadialProgressView non espone i campi - sono tutti privati, quindi semplicemente ereditare da RadialProgressView non ci permetterà di impostarli su un nuovo valore.

Tuttavia, siamo in grado di fare uso di reflection di modificare questi campi privati, in questo modo:

 var textPaintMember = typeof(RadialProgressView).GetField("textPaint", BindingFlags.Instance | BindingFlags.NonPublic); 
     textPaintMember.SetValue(Instance, MyNewSuperCoolColorPaint); 

Combinando i due, siamo in grado di trovare una nuova classe personalizzabile in questo modo:

public class CustomizableRadialProgressView : RadialProgressView 
{ 
    public CustomizableRadialProgressView(Context context) : base(context) 
    { 
    } 

    public void SetTextColor(Color color) 
    { 
     var paint = new Paint(); 
     paint.SetTypeface(Typeface.DefaultBold); 
     paint.Color = color; 
     paint.AntiAlias = true; 

     var textPaintMember = typeof(RadialProgressView).GetField("textPaint", BindingFlags.Instance | BindingFlags.NonPublic); 

     textPaintMember.SetValue(this, paint); 
    } 

    public void SetCircleColor(Color color) 
    { 
     var paint = new Paint(); 
     paint.SetStyle(Paint.Style.Fill); 
     paint.Color = color; 
     paint.AntiAlias = true; 

     var circlePaintMember = typeof(RadialProgressView).GetField("bgCirclePaint", BindingFlags.Instance | BindingFlags.NonPublic); 

     circlePaintMember.SetValue(this, paint); 
    } 

    public void SetBorderColor(Color color) 
    { 
     var paint = new Paint(); 
     paint.SetStyle(Paint.Style.Stroke); 
     paint.Color = color; 
     paint.AntiAlias = true; 

     var circlePaintMember = typeof(RadialProgressView).GetField("bgBorderPaint", BindingFlags.Instance | BindingFlags.NonPublic); 

     circlePaintMember.SetValue(this, paint); 
    } 


    public void SetProgressPackgroundColor(Color color) 
    { 
     var paint = new Paint(); 
     paint.SetStyle(Paint.Style.Stroke); 
     paint.Color = color; 
     paint.AntiAlias = true; 

     var circlePaintMember = typeof(RadialProgressView).GetField("bgProgressPaint", BindingFlags.Instance | BindingFlags.NonPublic); 

     circlePaintMember.SetValue(this, paint); 
    } 
} 

Questo ci otterrà il risultato che cerchiamo:

2

Nota: è probabilmente opportuno notare che stiamo facendo un uso improprio dei campi privati: li stiamo manipolando al di fuori della classe in cui vivono. Se Xamarin decide di cambiare il modo in cui è implementato RadialProgressView, o anche solo rinomina una delle variabili private, il nostro codice fallirà in fase di runtime. Il modo migliore per affrontare questo problema sarebbe probabilmente chiedere a Xamarin di fornire i getter/setter di cui hai bisogno. Ma, hey, è così molto più fresco in questo modo;)

+0

possiamo cambiare solo la parte centrale del squillare ? – SARATH

+0

@SarathiOS: non sono sicuro di aver capito la tua domanda. Quale parte vorresti cambiare anche tu? –

+0

la vista intorno a quella etichetta (40) che vista devo cambiare. È possibile ? – SARATH

1

Si può provare l'attuazione di un costume ViewRenderer e accedere alle sottostanti vista nativo Android per modificali come vuoi. https://blog.xamarin.com/using-custom-controls-in-xamarin.forms-on-android/

L'errore che avete per quanto riguarda il metodo "setBackgroundTintMode" indica che potrebbe essere necessario aggiornare la propria piattaforma Xamarin per assicurarsi che le ultime API sono disponibili

+0

ho implementato questa vista progressiva radiale nella mia app ios. Ma sfortunatamente non ho trovato nessuna opzione per cambiare il suo background. Area internaDevo cambiare il suo background in White – SARATH

+0

Hai qualche idea per cambiare il back ground di Radial Progress view. Grazie in anticipo – SARATH

+0

Credo che sia necessario accedere ai componenti sottostanti e modificare le loro proprietà, in Android se è possibile trasmettere RadialProgressView a un ViewGroup, è possibile accedere ai bambini tramite il metodo getChildAt (int index). –