如何自定义渲染器?

时间:2020-07-08 11:22:17

标签: c# xamarin xamarin.forms webview offline

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

离线时有关于Xamarin Webview加载网站的想法吗?

我一直在寻找这个,我只看到Java Android WebViews,什么也看不到Xamarin表单

2 个答案:

答案 0 :(得分:1)

我们可以使用自定义渲染器在iOS和Android上设置 CacheMode

形式

创建自定义WebView

interface InstructionListRequestsModel {

pageNumber?: number,
pageSize?: number,
sortBy?: InstructionSortBy,
order?: SortOrder,
observe?: 'body',
reportProgress?: boolean
}

export default class InstructionRequestListModel {
private dataModel: InstructionListRequestsModel;
private tableData: InstructionsResponse[] = [];
public totalRecords = 0;

constructor() {
    this.dataModel = {
        pageNumber: 1,
        pageSize: 25,       
        sortBy: InstructionSortBy.SCHEDULEDATE,
        order: SortOrder.ASCENDING
    };
}

get getModel() {
    return this.dataModel;
}

get getTableData() {
    return this.tableData;
}

public updateTableData = (data: any[]) => {
    this.tableData = data;
};

public updateDataModel = (propertyName: string, param: any) => {
    this.dataModel[propertyName] = param;
};
}

在iOS中

存在{strong> NSUrlRequestCachePolicy 的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); } } } 缓存类型。您可以将值设置为 NSURLRequestReturnCacheDataElseLoad

仅在没有缓存数据的情况下,才使用现有缓存数据(无论年龄,到期日期或到期日期)从原始源加载。

ReturnCacheDataElseLoad

在Android中


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);               
            }
        }
    }
}

现在,您只需要在xaml中定义它,如下所示


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;
            }

        }
    }
}

答案 1 :(得分:0)

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