代码之家  ›  专栏  ›  技术社区  ›  Denny

如何在android的xamarin表单中从customwebview渲染器更新progressbar?

  •  4
  • Denny  · 技术社区  · 6 年前

    WebView .

    在Android中,您可以使用ProgressBar和WebView来执行类似的操作 main_layout.xml

    public class MainActivity extends Activity {
    
        private ProgressBar progressBar;
        private WebView webView;    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {     
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main_layout);
    
            progressBar = (ProgressBar) findViewById(R.id.progress);
            webView = (AdvancedWebView) findViewById(R.id.webView);
            // webview initialisation
            webView.setWebChromeClient(new WebChromeClient(){
                @Override
                public void onProgressChanged(WebView view, int newProgress) {
                    // update progressbar progress
                    progressBar.setProgress(newProgress);
               }
           });
            webView.setWebViewClient(new WebViewClient(this) {
                @Override
                public void onPageFinished(WebView view, String url) {
                    // hide progressbar when it's done
                    progressBar.setVisibility(View.GONE);
                }
            });
        }
    }
    

    在Xamarin表单中,我有这个布局主页.xaml在共享项目中

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage
    x:Class="MainPage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    NavigationPage.HasNavigationBar="False">
    
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
    
        <ProgressBar
            x:Name="progress"
            Grid.Row="3"
            HorizontalOptions="FillAndExpand"
            Progress="0"
            VerticalOptions="Center" />
    
        <WebView
            x:Name="webview"
            Grid.Row="0"
            Grid.RowSpan="4"
            Grid.Column="0"
            HorizontalOptions="FillAndExpand"
            IsVisible="False"
            Source="https://google.com"
            VerticalOptions="FillAndExpand" />
    
    </Grid>
    

    public partial class App : Application
    {
        public App ()
        {
            InitializeComponent();
    
            MainPage = new MainPage(); 
        }
    }
    

    [assembly: ExportRenderer(typeof(WebView), typeof(CustomWebviewRenderer))]
    namespace MyApp.Droid
    {
        public class CustomWebviewRenderer: WebViewRenderer
        {
            private readonly Context context;
    
            public CustomWebviewRenderer(Context context) : base(context)
            {
                this.context = context;
            }
    
            protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
            {
                base.OnElementChanged(e);
                var formsWebView = e.NewElement as Xamarin.Forms.WebView;
    
                if (formsWebView != null)
                {
                    var webView = Control as Android.Webkit.WebView;
                    webView.SetWebViewClient(new CustomWebViewClient()); 
                    webView.SetWebChromeClient(new CustomWebChromeClient());     
                    webView.Settings.LoadWithOverviewMode = true;
                    webView.Settings.UseWideViewPort = true;
                    SetNativeControl(webView);
                }
            }
    
            private class ScoritoWebChromeClient : WebChromeClient
            {
                public override void OnProgressChanged(Android.Webkit.WebView view, int newProgress)
                {
                    // how to update progressbar progress?
                    base.OnProgressChanged(view, newProgress);               
                }
            }
    
            private class CustomWebViewClient : WebViewClient
            {
                public override void OnPageFinished(Android.Webkit.WebView view, string url)
                {
                    // how to hide progressbar?
                    base.OnPageFinished(view, url);
                }
    
                public override void OnPageStarted(Android.Webkit.WebView view, string url, Bitmap favicon)
                {
                    base.OnPageStarted(view, url, favicon);
                }
    
                public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView view, IWebResourceRequest request)
                {
                    return base.ShouldOverrideUrlLoading(view, request);
                }
            }
        }
    }
    

    如何更新我的ProgressBar主页.xaml从 OnPageFinished CustomWebviewRenderer 类以显示网页已完成加载?我应该用这个吗主活动.cs在Android项目中?

    有人能给我指出解决这个问题的正确方向吗?

    2 回复  |  直到 6 年前
        1
  •  0
  •   FreakyAli    6 年前

     public class CustomWebView: WebView
     {   
        public static readonly BindableProperty ActionProperty = BindableProperty.Create(propertyName: nameof(Action), returnType: typeof(Action),
            declaringType: typeof(CustomWebView),
            defaultValue: null,
            defaultBindingMode: BindingMode.OneWay);
    
        public void InvokeAction()
        {
            if (Action == null || data == null)
            {
                return;
            }
            Action.Invoke();
        }
    
        public Action Action
        {
            get { return (Action)GetValue(ActionProperty); }
            set { SetValue(ActionProperty, value); }
        }
    
     }
    

    将此CustomWebView与其命名空间一起使用,如下所示:

    <namespace:CustomWebView  x:Name="webview"
        Grid.Row="0"
        Grid.RowSpan="4"
        Grid.Column="0"
        HorizontalOptions="FillAndExpand"
        IsVisible="False"
        Source="https://google.com"
        VerticalOptions="FillAndExpand"/>  
    

    但如果仍然坚持使用渲染器,则可以使用element属性更新进度条,并获得回调或更改属性,如下所示:

    [assembly: ExportRenderer(typeof(CustomWebView), typeof(CustomWebviewRenderer))]
     namespace MyApp.Droid
    {
    public class CustomWebviewRenderer: WebViewRenderer
    {
        private readonly Context context;  
    
        public CustomWebviewRenderer(Context context) : base(context)
        {
            this.context = context;
        }
    
        protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
        {
            base.OnElementChanged(e);
            var formsWebView = e.NewElement as Xamarin.Forms.WebView;
    
            if (formsWebView != null)
            {
                var webView = Control as Android.Webkit.WebView;
                webView.SetWebViewClient(new CustomWebViewClient()); 
                webView.SetWebChromeClient(new CustomWebChromeClient());     
                webView.Settings.LoadWithOverviewMode = true;
                webView.Settings.UseWideViewPort = true;
                SetNativeControl(webView);
            }
        }
    
        private class ScoritoWebChromeClient : WebChromeClient
        {
            public override void OnProgressChanged(Android.Webkit.WebView view, int newProgress)
            {
                // how to update progressbar progress?
                base.OnProgressChanged(view, newProgress);               
            }
        }
    
        private class CustomWebViewClient : WebViewClient
        {
            private _webView;
            public CustomWebViewClient (Xamarin.Forms.WebView webView) 
            {
              _webView=webView;
            }
            public override void OnPageFinished(Android.Webkit.WebView view, string url)
            {
                // how to hide progressbar?
                _webView.InvokeAction();
                base.OnPageFinished(view, url);
            }
    
            public override void OnPageStarted(Android.Webkit.WebView view, string url, Bitmap favicon)
            {
                base.OnPageStarted(view, url, favicon);
            }
    
            public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView view, IWebResourceRequest request)
            {
                return base.ShouldOverrideUrlLoading(view, request);
            }
        }
      }
    }   
    

    请注意,这只是一个示例,可以根据您的要求进行更改。

    以防它不起作用或你有问题!

        2
  •  0
  •   Denny    6 年前

    那以后呢 10天 我终于找到了解决这个问题的方法 bindableproperties ...

    所以我加了一个 CustomWebView 在PCL中

    public class CustomWebView : WebView
    {
        public static readonly BindableProperty PageProgressProperty = BindableProperty.Create(
            nameof(PageProgress),
            typeof(int),
            typeof(CustomWebView),
            default(int));
    
        public int PageProgress
        {
            get => (int)GetValue(PageProgressProperty);
            set => SetValue(PageProgressProperty, value);
        }      
    }
    

    CustomProgressBar 在PCL中

    public class CustomProgressBar : ProgressBar
    {
        public CustomProgressBar()
        {
        }
    
        public static readonly BindableProperty CurrentProgressProperty =
        BindableProperty.Create(
            nameof(CurrentProgress),
            typeof(int),
            typeof(CustomProgressBar),
            default(int),
            propertyChanged: CustomProgressPropertyChanged);
    
        private static void CustomProgressPropertyChanged(BindableObject sender, object oldValue, object newValue)
        {
            CustomProgressBar thisProgressBar = (CustomProgressBar)sender;
            double percent = Convert.ToDouble(newValue) / 100;
            thisProgressBar.ProgressTo(percent, 100, Easing.Linear);
        }
    
        public int CurrentProgress
        {
            get => (int)GetValue(CurrentProgressProperty);
            set => SetValue(CurrentProgressProperty, value);
        }
    }
    

    现在我可以从我的 CustomWebviewRenderer 如下

    public class CustomWebviewRenderer : WebViewRenderer
    {
        private readonly Context context;
    
        public CustomWebviewRenderer(Context context) : base(context)
        {
            this.context = context;
        }
    
        protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
        {
            base.OnElementChanged(e);
            var formsWebView = e.NewElement as WebView;
    
            if (e.OldElement == null)
            {
                var x = Control;
                var webView = Control as Android.Webkit.WebView;
                webView.SetWebViewClient(new CustomWebViewClient(Element));
                webView.SetWebChromeClient(new CustomWebChromeClient(Element));
                webView.Settings.LoadWithOverviewMode = true;
                SetNativeControl(webView);
            }
        }
    
        private class CustomWebViewClient : WebViewClient
        {
            private readonly WebView formsWebView;
    
            public CustomWebViewClient(WebView webView)
            {
                formsWebView = webView;
            }
    
            public override void OnReceivedError(Android.Webkit.WebView view, IWebResourceRequest request, WebResourceError error)
            {
                base.OnReceivedError(view, request, error);
            }
    
            public override void OnPageFinished(Android.Webkit.WebView view, string url)
            {
                base.OnPageFinished(view, url);
            }
    
            public override void OnPageStarted(Android.Webkit.WebView view, string url, Bitmap favicon)
            {
                base.OnPageStarted(view, url, favicon);
            }
    
            public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView view, IWebResourceRequest request)
            {
                return base.ShouldOverrideUrlLoading(view, request);
            }
        }
    
        private class CustomWebChromeClient : WebChromeClient
        {
            private WebView element;
    
            public CustomWebChromeClient(WebView element)
            {
                this.element = element;
            }
    
            public override void OnProgressChanged(Android.Webkit.WebView view, int newProgress)
            {
                base.OnProgressChanged(view, newProgress);
                element.SetValueFromRenderer(CustomWebView.PageProgressProperty, newProgress);
            }          
        }
    }
    

    BindingContext CurrentProgress . 这个 绑定上下文 当前进度 PageProgress 这是一个住在 自定义Web视图

        <local:CustomProgressBar
            x:Name="progress"
            Grid.Row="3"
            BindingContext="{x:Reference webview}"
            CurrentProgress="{Binding Path=PageProgress}"
            HorizontalOptions="FillAndExpand"
            ProgressColor="#FFB800"
            VerticalOptions="Center" />
    
        <local:CustomWebView
            x:Name="webview"
            Grid.Row="0"
            Grid.RowSpan="4"
            Grid.Column="0"
            HorizontalOptions="FillAndExpand"
            IsVisible="False"
            VerticalOptions="FillAndExpand" />