Embed a WebView in SfShimmer

Hello,

I'm trying to embed a WebView in the SfShimmer: I would like to display a skeleton while data are loading.

For this, I've created a custom WebView, allowing me to access to WebNavigatingEventArgs/WebNavigatedEventArgs in the ViewModel.

public class BookingWebView : WebView
{

    public static readonly BindableProperty NavigatingCommandProperty =
        BindableProperty.Create(nameof(NavigatingCommand), typeof(ICommand), typeof(BookingWebView), null);

    public ICommand NavigatingCommand
    {
        get { return (ICommand)GetValue(NavigatingCommandProperty); }
        set { SetValue(NavigatingCommandProperty, value); }
    }

    public static readonly BindableProperty NavigatedCommandProperty =
        BindableProperty.Create(nameof(NavigatedCommand), typeof(ICommand), typeof(BookingWebView), null);

    public ICommand NavigatedCommand
    {
        get { return (ICommand)GetValue(NavigatedCommandProperty); }
        set { SetValue(NavigatedCommandProperty, value); }
    }


    public BookingWebView()
    {
        WebViewClass _WebViewClass = new WebViewClass();

        Navigating += (s, navigating) =>
        {
            _WebViewClass.sender = s;
            _WebViewClass.navigating = navigating;
            if (NavigatingCommand?.CanExecute(navigating) ?? false)
                NavigatingCommand.Execute(_WebViewClass);
        };

        Navigated += (s, navigated) =>
        {
            _WebViewClass.sender = s;
            _WebViewClass.navigated = navigated;
            if (NavigatedCommand?.CanExecute(navigated) ?? false)
                NavigatedCommand.Execute(_WebViewClass);
        };

    }
}

public class WebViewClass
{
    public object sender { get; set; }
    
    public WebNavigatingEventArgs navigating { get; set; }
    public WebNavigatedEventArgs navigated { get; set; }    
}

The XAML of my Booking page is like: 

<shimmer:SfShimmer x:Name="shimmer" VerticalOptions="Fill">
    <shimmer:SfShimmer.IsActive>
        <MultiBinding Converter="{StaticResource AllTrueConverter}">
            <Binding Path="IsBusy" />
            <Binding Path="IsFirstDisplay" />
        </MultiBinding>
    </shimmer:SfShimmer.IsActive>
    <shimmer:SfShimmer.Content>
        <ctrl:BookingWebView x:Name="webView" Source="{Binding UrlBooking}"
                                WidthRequest="1000" HeightRequest="1000"
                                NavigatedCommand="{Binding WebViewNavigatedCommand}"
                                NavigatingCommand="{Binding WebViewNavigatingCommand}"/>
    </shimmer:SfShimmer.Content>
</shimmer:SfShimmer>

Then my ViewModel is like this:

public class BookingViewModel : AvilaViewModelBase
{
    string avilaUrlBooking = "https://my.url.booking";
    public string AvilaUrlBooking
    {
        get { return avilaUrlBooking; }
        set { SetProperty(ref avilaUrlBooking, value); }
    }

    public AsyncCommand WebViewNavigatingCommand => new AsyncCommand(this.WebViewNavigating);
    public AsyncCommand WebViewNavigatedCommand => new AsyncCommand(this.WebViewNavigated);

    bool isFirstDisplay;
    public bool IsFirstDisplay
    {
        get { return isFirstDisplay; }
        set { SetProperty(ref isFirstDisplay, value); }
    }

    public BookingViewModel()
    {
        IsFirstDisplay = true;
        Title = "Booking";
    }

    private async Task WebViewNavigating()
    {
        IsBusy = true;
    }

    private async Task WebViewNavigated()
    {
        IsBusy = false;
        IsFirstDisplay = false;
    }
}

But in this case, the WebView is never displayed: I only see the Shimmer.
The Navigating event is well fired, but not the Navigated event.

If I comment the IsBusy lines in the ViewModel, the WebView is well displayed and the Shimmer is not displayed


Is this behaviour normal?





Attachment: Archive_667f3cb5.zip

8 Replies 1 reply marked as answer

RS Ramya Soundar Rajan Syncfusion Team November 2, 2020 01:56 PM UTC

Hi Pierre-Christophe DUS,  
 
Greetings from Syncfusion. 
 
We would like to let you know that when disabling the IsActive property of the SfShimmer to show the content of the SfShimmer and if the property is enabled then the control will be rendered. Please refer the below help document link for more information. 
 
 
We have checked the reported problem based on your provided code snippet in a simple sample and it’s working fine in our side. And also checked in button click to enable/disable the IsActive property. Please refer the below sample. 
 
 
Configuration details: 

 
Android Device : HUAWEI PRA, MI A3
iOS version : 12.0 
Syncfusion Version : 18.3.0.44 
Xamarin Forms Version : 4.8

 
Query: The Navigating event is well fired, but not the Navigated event. 
 
We suspect that the reported query it’s a framework level problem. Please find the below link for more information. 
 
 
Can you please check the attached sample and please Share the following details? 

 
·       If possible, could you please share the sample to replicate this issue or modify the above sample to reproduce. 
·       Can you share the model and converter class to check in our side? 
·       Please provide the parent view structure where the SfShimmer added.  
·       Is it occurred with the specific devices or else to common? In addition, please share the used device. 
·       Can you please provide the whole structure which is used in your application?

 
This will be helpful for us to investigate further and provide you a better solution at the earliest. 
 
Regards, 
Ramya S 



PD Pierre-Christophe DUS November 3, 2020 06:25 PM UTC

Hi Ramya Soundar Rajan, thanks for your answer.

After having investigated, it seems that the issue is coming from the 
SfShimmer.CustomView

If I use the SfShimmer without a CustomView, all is working fine on iOS and Android.

But if I use the CustomView, it seems that there are problems on iOS and AndroidIf we use the default WebView implementation, we can see that Navigating event is fired, but not the Navigated event: so the SfShimmer is always visible, as IsBusy is never set to false.

In add, I've created a custom renderer for the iOS WebView, cause, as you said, there are some errors related to these events in case of errors (timeout, server error, ...). So in this case, when I use the SfShimmer without a CustomView, all is working fine on iOS. But when I add the CustomView I got an exception that occurs in the renderer.

I've attached a small project that which allow you to reproduce these cases, on iOS and Android: you will just have to comment/uncomment the CustomView in 
MainPageMvvmDon't hesitate to come back to me if you need some help to achieve this...






Attachment: WebviewDebug_feecd675.zip


SS Sridevi Sivakumar Syncfusion Team November 4, 2020 03:53 PM UTC

Hi Pierre-Christophe DUS,

Thanks for your update,

We have forwarded your query to the development team and update the further details on or before November 6, 2020.


Regards,
Sridevi S.
 



HM Hemalatha Marikumar Syncfusion Team November 8, 2020 07:17 AM UTC

Hi Pierre-Christophe DUS, 
 
Sorry for the delay. 
 
We would like to let you know that Shimmer is also having the base of ContentView. We are switching the content of that ContentView when changing the IsActive property. Hence for old content, WebView navigated event is not fired properly and same has been reproduced with simple ContentView also as per in below 
  
ContentView x:Name="contentView" Grid.Row="1" > 
            <ContentView.Content> 
                <WebView x:Name="webView" WidthRequest="1000" HeightRequest="1000" 
                         Navigating="WebView_Navigating" Navigated="WebView_Navigated" /> 
            </ContentView.Content> 
        </ContentView> 
  
  
  
private async void WebView_Navigating(object sender, WebNavigatingEventArgs e) 
        { 
            contentView.Content = new Button() 
            { 
                WidthRequest = 30, 
                HeightRequest = 30 
            };        } 
  
private async void WebView_Navigated(object sender, WebNavigatedEventArgs e) 
{ 
    contentView.Content = webView;        
 } 
  
  

On further analysis our development team provides a workaround solution to resolve the reported problem. In this sample, we have added the WebView outside the SfShimmer control. Please have a sample from the below link.

Link: 
https://www.syncfusion.com/downloads/support/forum/159263/ze/Sample-278569697

Code Snippet:

 
  <Grid  Grid.Row="1"> 
                <Grid.RowDefinitions>                                                                 
                    <RowDefinition Height="100"/> 
                    <RowDefinition Height="*"/> 
                </Grid.RowDefinitions> 
                <Grid Grid.Row="1"> 
                    <controls:CustomWebView x:Name="webView"> 
   ... 
                     </controls:CustomWebView> 
 
                    <shimmer:SfShimmer x:Name="shimmer" 
...                         > 
 
                        <shimmer:SfShimmer.CustomView> 
  ...                       
                        </shimmer:SfShimmer.CustomView> 
 
 
                    </shimmer:SfShimmer> 
                </Grid> 
            </Grid> 
  
Regards,
Hemalatha M. 



PD Pierre-Christophe DUS November 9, 2020 11:27 AM UTC

Hi Hemalatha Marikumar,

Thanks for your answer.

I'm not sure to understand your suggestion or what has been done in the sample project...

In add,  on Android, the SfShimmer is displayed above and in the same time than the WebView during the "Refresh"
And on iOS, I only see the SfShimmer, but never the WebView (after the first loading, or after the "Refresh")

So I can't use your solution.



RS Ramya Soundar Rajan Syncfusion Team November 11, 2020 12:36 PM UTC

Hi Pierre-Christophe DUS, 
 
We have modified your provided sample to resolve the reported problems by adding the WebView outside the SfShimmer and set the BackgroundColor and updated the IsVisible property of the grid as like in below code. 
 
  … 
 
                    <controls:CustomWebView x:Name="webView" 
                                            Source="{Binding MyUrlBooking}" 
                                            Uri="{Binding MyUrlBooking}" 
                                            WidthRequest="1000" HeightRequest="1000" 
                                            NavigatingCommand="{Binding WebViewNavigatingCommand}" 
                                            NavigatedCommand="{Binding WebViewNavigatedCommand}"> 
                        
                     
 
                    </controls:CustomWebView> 
 
                    <Grid BackgroundColor="White" IsVisible="{Binding IsBusy, Mode=TwoWay}"> 
                        <shimmer:SfShimmer x:Name="shimmer" VerticalOptions="FillAndExpand" 
                               IsActive="{Binding IsBusy, Mode=TwoWay}" > 
 
                            <shimmer:SfShimmer.CustomView> 
                                <Grid> 
                                    <Grid.RowDefinitions> 
                                        <RowDefinition Height="30" /> 
                                        <RowDefinition Height="30" /> 
                                        <RowDefinition Height="90" /> 
                                        <RowDefinition Height="90" /> 
                                        <RowDefinition Height="90" /> 
                                        <RowDefinition Height="*" /> 
                                    </Grid.RowDefinitions> 
                                    <Grid.ColumnDefinitions> 
                                        <ColumnDefinition Width="*" /> 
                                        <ColumnDefinition Width="90" /> 
                                        <ColumnDefinition Width="*" /> 
                                        <ColumnDefinition Width="90" /> 
                                        <ColumnDefinition Width="*" /> 
                                    </Grid.ColumnDefinitions> 
                                    <BoxView Grid.Row="0" Grid.Column="0" 
                                    HorizontalOptions="Start" 
                                    WidthRequest="20" 
                                    BackgroundColor="{StaticResource Gray-400}" /> 
                                    <BoxView Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="3" 
                                    HorizontalOptions="StartAndExpand" 
                                    WidthRequest="150" 
                                    BackgroundColor="{StaticResource Gray-400}" /> 
                                    <BoxView Grid.Row="0" Grid.Column="4" 
                                    HorizontalOptions="Start" 
                                    WidthRequest="20" 
                                    BackgroundColor="{StaticResource Gray-400}" /> 
                                </Grid> 
                            </shimmer:SfShimmer.CustomView> 
 
 
                        </shimmer:SfShimmer> 
                    </Grid> 
    … 
 
 
 
 
Note: The SfShimmer custom view effects will be differ in Android and iOS Platforms. Is it fine for your project.? If you need custom view effects will be same for both the platforms, can you please share the exact design of the custom view used inside the shimmer in your project. We will check and update in our side further. 
 
Regards, 
Ramya S 


Marked as answer

PD Pierre-Christophe DUS November 11, 2020 03:52 PM UTC

Thanks Ramya, 

Finally I have removed SfShimmer and I now use Lottie to display an animation during loading.

Regards,


RS Ramya Soundar Rajan Syncfusion Team November 16, 2020 01:03 PM UTC

Hi Pierre-Christophe DUS, 
 
Sorry for the inconvenience caused and really apology for your disappointing.  
 
Could you please check the sample and confirm whether your required shimmer effects is from Android or else in iOS? If that required is from Android, then we will check the possibility to obtain the same behavior in iOS or Vice versa. 
 
Regards, 
Ramya S 


Loader.
Up arrow icon