如何自定义渲染器?

How custom renderer?

我正在使用 Xamarin WebView,并希望我的 Xamarin 应用程序在离线时仍能加载网站。

离线时Xamarin Webview加载网站有什么想法吗?

我一直在搜索这个,我只看到 Java Android WebViews 而没有看到 Xamarin 表单

我们可以使用 Custom Renderer 在 iOS 和 Android 上设置 CacheMode

在表格中

创建自定义 WebView

public class MyWebView : WebView
{
    public static readonly BindableProperty UrlProperty = BindableProperty.Create(
    propertyName: "Url",
    returnType: typeof(string),
    declaringType: typeof(MyWebView),
    defaultValue: default(string));

    public string Url
    {
        get { return (string)GetValue(UrlProperty); }
        set { SetValue(UrlProperty, value); }
    }
}

在iOS

有一个 ReturnCacheDataElseLoad 缓存类型 NSUrlRequestCachePolicy 。您可以将值设置为 NSURLRequestReturnCacheDataElseLoad .

Use existing cache data, regardless or age or expiration date, loading from originating source only if there is no cached data.


using System.ComponentModel;

using xxx;
using xxx.iOS;
using Foundation;
using UIKit;
using WebKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly:ExportRenderer(typeof(MyWebView),typeof(MyWebViewRenderer))]
namespace xxx.iOS
{
    public class MyWebViewRenderer : ViewRenderer<MyWebView, WKWebView>
    {
        WKWebView _wkWebView;

        protected override void OnElementChanged(ElementChangedEventArgs<MyWebView> e)
        {
            base.OnElementChanged(e);

            if (Control == null)
            {
                var config = new WKWebViewConfiguration();
                _wkWebView = new WKWebView(Frame, config);
                SetNativeControl(_wkWebView);
            }
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            if (e.PropertyName == "Url")
            {
                NSUrlRequest request = new NSUrlRequest(new NSUrl(Element.Url), NSUrlRequestCachePolicy.ReturnCacheDataElseLoad, 5);
                Control.LoadRequest(request);               
            }
        }
    }
}

在Android


using Android.Content;

using xxx;
using xxx.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(MyWebView), typeof(MyWebViewRenderer))]
namespace xxx.Droid
{
    public class MyWebViewRenderer : WebViewRenderer
    {
        public MyWebViewRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
        {
            base.OnElementChanged(e);

            if(Control!=null)
            {
                Control.Settings.CacheMode = Android.Webkit.CacheModes.CacheElseNetwork;
                Control.Settings.JavaScriptEnabled = true;
            }

        }
    }
}

现在你只需要在xaml中像下面这样定义它

<local:MyWebView Url="xxx" />

我在 Android 自定义渲染器中添加了 Control.LoadUrl(((MyWebView)Element).Url); 行,否则 url 不会显示。此外 OnElementPropertyChanged if(e.property==url) 永远不会是真的我将此块移动到 iOS 渲染器中的 OnElementChanged 方法。