Integrazione con Xamarin.Forms

Download Sample Scaricare l'esempio

Creare grafica SkiaSharp che rispondano al tocco e Xamarin.Forms agli elementi

La grafica SkiaSharp può integrarsi con il resto di Xamarin.Forms in diversi modi. È possibile combinare un'area di disegno e Xamarin.Forms elementi SkiaSharp nella stessa pagina e persino posizionare Xamarin.Forms gli elementi sopra un'area di disegno SkiaSharp:

Selecting a color with sliders

Un altro approccio alla creazione di grafica SkiaSharp interattiva in Xamarin.Forms è tramite tocco. La seconda pagina del programma SkiaSharpFormsDemos è intitolata Tap Toggle Fill. Disegna un cerchio semplice in due modi, senza un riempimento e con un riempimento, attivato da un tocco. La TapToggleFillPage classe mostra come modificare la grafica SkiaSharp in risposta all'input dell'utente.

Per questa pagina, la SKCanvasView classe viene creata un'istanza nel file TapToggleFill.xaml , che imposta anche un oggetto Xamarin.FormsTapGestureRecognizer nella visualizzazione:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
             x:Class="SkiaSharpFormsDemos.TapToggleFillPage"
             Title="Tap Toggle Fill">

    <skia:SKCanvasView PaintSurface="OnCanvasViewPaintSurface">
        <skia:SKCanvasView.GestureRecognizers>
            <TapGestureRecognizer Tapped="OnCanvasViewTapped" />
        </skia:SKCanvasView.GestureRecognizers>
    </skia:SKCanvasView>
</ContentPage>

Si noti la skia dichiarazione dello spazio dei nomi XML.

Il Tapped gestore per l'oggetto TapGestureRecognizer semplicemente attiva o disattiva il valore di un campo booleano e chiama il InvalidateSurface metodo di SKCanvasView:

bool showFill = true;
...
void OnCanvasViewTapped(object sender, EventArgs args)
{
    showFill ^= true;
    (sender as SKCanvasView).InvalidateSurface();
}

La chiamata a InvalidateSurface genera in modo efficace una chiamata al PaintSurface gestore, che usa il showFill campo per riempire o meno il cerchio:

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    SKImageInfo info = args.Info;
    SKSurface surface = args.Surface;
    SKCanvas canvas = surface.Canvas;

    canvas.Clear();

    SKPaint paint = new SKPaint
    {
        Style = SKPaintStyle.Stroke,
        Color = Color.Red.ToSKColor(),
        StrokeWidth = 50
    };
    canvas.DrawCircle(info.Width / 2, info.Height / 2, 100, paint);

    if (showFill)
    {
        paint.Style = SKPaintStyle.Fill;
        paint.Color = SKColors.Blue;
        canvas.DrawCircle(info.Width / 2, info.Height / 2, 100, paint);
    }
}

La StrokeWidth proprietà è stata impostata su 50 per accentuare la differenza. È anche possibile visualizzare l'intera larghezza della linea disegnando prima l'interno e quindi il contorno. Per impostazione predefinita, le figure grafiche disegnate più avanti nel PaintSurface gestore eventi oscurano quelle disegnate in precedenza nel gestore.

La pagina Esplora colori illustra come integrare anche la grafica SkiaSharp con altri Xamarin.Forms elementi e dimostra anche la differenza tra due metodi alternativi per la definizione dei colori in SkiaSharp. Il metodo statico SKColor.FromHsl crea un SKColor valore basato sul modello Hue-Saturation-Light:

public static SKColor FromHsl (Single h, Single s, Single l, Byte a)

Il metodo statico SKColor.FromHsv crea un SKColor valore basato sul modello Hue-Saturation-Value simile:

public static SKColor FromHsv (Single h, Single s, Single v, Byte a)

In entrambi i casi, l'argomento h è compreso tra 0 e 360. Gli sargomenti , le v sono compresi tra 0 e 100. L'argomento a (alfa o opacità) varia da 0 a 255.

Il file ColorExplorePage.xaml crea due SKCanvasView oggetti StackLayout affiancati a Slider e Label visualizzazioni che consentono all'utente di selezionare i valori di colore HSL e HSV:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
             x:Class="SkiaSharpFormsDemos.Basics.ColorExplorePage"
             Title="Color Explore">
    <StackLayout>
        <!-- Hue slider -->
        <Slider x:Name="hueSlider"
                Maximum="360"
                Margin="20, 0"
                ValueChanged="OnSliderValueChanged" />

        <Label HorizontalTextAlignment="Center"
               Text="{Binding Source={x:Reference hueSlider},
                              Path=Value,
                              StringFormat='Hue = {0:F0}'}" />

        <!-- Saturation slider -->
        <Slider x:Name="saturationSlider"
                Maximum="100"
                Margin="20, 0"
                ValueChanged="OnSliderValueChanged" />

        <Label HorizontalTextAlignment="Center"
               Text="{Binding Source={x:Reference saturationSlider},
                              Path=Value,
                              StringFormat='Saturation = {0:F0}'}" />

        <!-- Lightness slider -->
        <Slider x:Name="lightnessSlider"
                Maximum="100"
                Margin="20, 0"
                ValueChanged="OnSliderValueChanged" />

        <Label HorizontalTextAlignment="Center"
               Text="{Binding Source={x:Reference lightnessSlider},
                              Path=Value,
                              StringFormat='Lightness = {0:F0}'}" />

        <!-- HSL canvas view -->
        <Grid VerticalOptions="FillAndExpand">
            <skia:SKCanvasView x:Name="hslCanvasView"
                               PaintSurface="OnHslCanvasViewPaintSurface" />

            <Label x:Name="hslLabel"
                   HorizontalOptions="Center"
                   VerticalOptions="Center"
                   BackgroundColor="Black"
                   TextColor="White" />
        </Grid>

        <!-- Value slider -->
        <Slider x:Name="valueSlider"
                Maximum="100"
                Margin="20, 0"
                ValueChanged="OnSliderValueChanged" />

        <Label HorizontalTextAlignment="Center"
               Text="{Binding Source={x:Reference valueSlider},
                              Path=Value,
                              StringFormat='Value = {0:F0}'}" />

        <!-- HSV canvas view -->
        <Grid VerticalOptions="FillAndExpand">
            <skia:SKCanvasView x:Name="hsvCanvasView"
                               PaintSurface="OnHsvCanvasViewPaintSurface" />

            <Label x:Name="hsvLabel"
                   HorizontalOptions="Center"
                   VerticalOptions="Center"
                   BackgroundColor="Black"
                   TextColor="White" />
        </Grid>
    </StackLayout>
</ContentPage>

I due SKCanvasView elementi si trovano in una singola cella Grid con una Label seduta in alto per visualizzare il valore di colore RGB risultante.

Il file code-behind ColorExplorePage.xaml.cs è relativamente semplice. Il gestore condiviso ValueChanged per i tre Slider elementi invalida semplicemente entrambi SKCanvasView gli elementi. I PaintSurface gestori cancellano l'area di disegno con il colore indicato dagli Slider elementi e impostano anche l'oggetto Label seduto sopra gli SKCanvasView elementi:

public partial class ColorExplorePage : ContentPage
{
    public ColorExplorePage()
    {
        InitializeComponent();

        hueSlider.Value = 0;
        saturationSlider.Value = 100;
        lightnessSlider.Value = 50;
        valueSlider.Value = 100;
    }

    void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
    {
        hslCanvasView.InvalidateSurface();
        hsvCanvasView.InvalidateSurface();
    }

    void OnHslCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
    {
        SKColor color = SKColor.FromHsl((float)hueSlider.Value,
                                        (float)saturationSlider.Value,
                                        (float)lightnessSlider.Value);
        args.Surface.Canvas.Clear(color);

        hslLabel.Text = String.Format(" RGB = {0:X2}-{1:X2}-{2:X2} ",
                                      color.Red, color.Green, color.Blue);
    }

    void OnHsvCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
    {
        SKColor color = SKColor.FromHsv((float)hueSlider.Value,
                                        (float)saturationSlider.Value,
                                        (float)valueSlider.Value);
        args.Surface.Canvas.Clear(color);

        hsvLabel.Text = String.Format(" RGB = {0:X2}-{1:X2}-{2:X2} ",
                                      color.Red, color.Green, color.Blue);
    }
}

Nei modelli di colore HSL e HSV il valore Hue è compreso tra 0 e 360 e indica la tonalità dominante del colore. Questi sono i colori tradizionali dell'arcobaleno: rosso, arancione, giallo, verde, blu, indaco, viola e indietro in un cerchio da rosso.

Nel modello HSL, un valore 0 per La leggerezza è sempre nero e un valore 100 è sempre bianco. Quando il valore di saturazione è 0, i valori di leggerezza compresi tra 0 e 100 sono sfumature di grigio. L'aumento della saturazione aggiunge più colore. I colori puri (che sono valori RGB con un componente uguale a 255, un altro uguale a 0 e il terzo compreso tra 0 e 255) si verificano quando la saturazione è 100 e la leggerezza è 50.

Nel modello HSV i colori puri risultano quando sia la saturazione che il valore sono 100. Quando Value è 0, indipendentemente da qualsiasi altra impostazione, il colore è nero. Le sfumature grigie si verificano quando la saturazione è 0 e Value è compreso tra 0 e 100.

Ma il modo migliore per provare i due modelli è sperimentare con loro stessi:

Triple screenshot of the Color Explore page