Search code examples
androidxamarin.formsscrollviewdrawingskiasharp

SkiaSharp canvas in ScrollView is still scrolling when drawing


I cannot find a solution to this what seems a simple issue. I have created a simple skisharp finger painting area which is at the bottom of a scrollview in android Xamarin Forms. this works how ever only for a second as the page will scroll as I draw on the canvas. Any way to stop this? as i cannot actually draw anything cause the line dissapears once scroll begins

<ContentPage.Content>
    <ScrollView>
        <StackLayout>
            <Label x:Name="WeatherConditionLabel" Text="Weather/Condition" FontSize="20" FontAttributes="Bold"/>
            <Grid>
                <Label Text="Day/Night:"
                   FontSize="Medium"
           VerticalOptions="Center" />
            </Grid>
            <Switch HorizontalOptions="Start" IsToggled="false" Scale="1.8" Margin="20"/>
            <Grid Margin="20,10,10,20">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="0.40*" />
                    <ColumnDefinition Width="0.15*" />
                    <ColumnDefinition Width="0.25*" />
                    <ColumnDefinition Width="0.20*" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Label Text="Raining:"
                   FontSize="Medium"
           VerticalOptions="Center" />
                <CheckBox Grid.Column="1"
              Color="Turquoise"
              VerticalOptions="Center"
              Scale="1.6"
              x:Name="rainingCheck"/>
                <Label Grid.Column="2"
           Text="Snowing:"
                   FontSize="Medium"
           VerticalOptions="Center" />
                <CheckBox Grid.Column="3"
              Color="Turquoise"
              VerticalOptions="Center" 
              Scale="1.6"
              x:Name="snowingCheck"/>
                <Label Grid.Row="1"
           Text="Fog/Mist:"
                   FontSize="Medium"
           VerticalOptions="Center" />
                <CheckBox Grid.Row="1"
              Grid.Column="1"
              Color="Turquoise"
              Scale="1.6"
              VerticalOptions="Center"
              x:Name="FogMistCheck"/>
            </Grid>
            <Label x:Name="VehicleConditionImageLabel" Text="Vehicle Condition" FontSize="20" FontAttributes="Bold"/>
            <xct:DrawingView x:Name="damageDrawing" HeightRequest="200" DefaultLineColor="green" ClearOnFinish="False" ></xct:DrawingView>
            <Grid Margin="5,5,5,5">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="35*" />
                    <ColumnDefinition Width="30*" />
                    <ColumnDefinition Width="35*" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="40" />
                </Grid.RowDefinitions>
                <Button x:Name="greenBtn" VerticalOptions="Center" BackgroundColor="Green" />
                <Button Grid.Column="1" x:Name="amberBtn" VerticalOptions="Center" BackgroundColor="Yellow" />
                <Button Grid.Column="2" x:Name="rebBtn" VerticalOptions="Center" BackgroundColor="red" Clicked="redBtnPressed" />
            </Grid>

            <Grid BackgroundColor="White">
                <skia:SKCanvasView x:Name="canvasView"
                       HeightRequest="200"            
                       PaintSurface="OnCanvasViewPaintSurface" />
                <Grid.Effects>
                    <tt:TouchEffect Capture="True"
                        TouchAction="OnTouchEffectAction" />
                </Grid.Effects>
            </Grid>
        </StackLayout>
    </ScrollView>
</ContentPage.Content>

Solution

  • You can use the custom renderer to disable and enable the scrolling in the scrollview.

    1. Declare the custom scrollview in the share project:
        public class MyScrollView : ScrollView
        {
            public bool ScrollingEnabled = true;
        }
    
    1. Declare the custom renderer in the android project:
    [assembly: ExportRenderer(typeof(MyScrollView), typeof(MyScrollViewRenderer))]
    
    namespace XamarinFormsApp2.Droid
    {
        public class MyScrollViewRenderer : ScrollViewRenderer
        {
            public MyScrollViewRenderer(Context context) : base(context)
            {
                /* nothing here */
            }
    
            protected override void OnElementChanged(VisualElementChangedEventArgs e)
            {
                base.OnElementChanged(e);
            }
    
            public override bool OnInterceptTouchEvent(MotionEvent ev)
            {
                if (((MyScrollView)Element).ScrollingEnabled)
                {
                    return base.OnInterceptTouchEvent(ev);
                }
                else
                {
                    return false;
                }
            }
    
    
            public override bool OnTouchEvent(MotionEvent ev)
            {
                if (((MyScrollView)Element).ScrollingEnabled)
                {
                    return base.OnTouchEvent(ev);
                }
                else
                {
                    return false;
                }
            }
        }
    
    }
    
    1. Use the custom view in the xaml:
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:local="clr-namespace:XamarinFormsApp2"
                 x:Class="XamarinFormsApp2.MainPage">
        <local:MyScrollView x:Name="scroll">
    
    1. Disable the scrolling:
    private void Button_Clicked(object sender, EventArgs e)
     {
         scroll.ScrollingEnabled = false;
     }