问题描述
我是 Xamarin.Forms
的新手,我在 Droid
项目中实现了一个自定义 Web 视图渲染器.
I'm new with Xamarin.Forms
and I have implemented a custom web view renderer in Droid
project.
问题是在 iOS
项目中实现渲染器时,就像在没有加载 CSS 和 Javascript 的情况下初始化 Webview
一样.因为它只显示 HTML
页面,没有任何功能.
The issue is when implementing the renderer in iOS
project, it's like the Webview
is initialized without loading the CSS and Javascript. Because it only display HTML
page without any functionality.
经过一些研究,我知道我们必须实现 WKWebviewRenderer
并且我们必须在 iOS
中加载 LoadFileUrl
方法,但我仍然可以't 在渲染器中捕获 url.
After some research, I know we have to implement WKWebviewRenderer
and we have to load the LoadFileUrl
method in iOS
but I still can't catch the url in the renderer.
任何人都知道如何将以下 Android Renderer
代码实现到 iOS Renderer
??
Anyone have an idea please about how to implement the following Android Renderer
code into iOS Renderer
??
Droid 项目中的自定义渲染器:
[assembly: ExportRenderer(typeof(Xamarin.Forms.WebView), typeof(MyProject.Droid.WebViewRenderer))]
namespace MyProject.Droid
{
public class WebViewRenderer : Xamarin.Forms.Platform.Android.WebViewRenderer
{
private bool isMyCustomWebview = false;
public IWebViewController ElementController => Element;
protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
if (e.NewElement.GetType() == typeof(MyCustomWebview))
{
Control.SetWebViewClient(new Callback(this));
isMyCustomWebview = true;
}
else
{
Control.SetWebViewClient(new Callback(Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity));
isMyCustomWebview = false;
}
}
public class Callback : WebViewClient
{
Activity _context;
public Callback(Activity _context)
{
this._context = _context;
}
WebViewRenderer _renderer;
public Callback(WebViewRenderer renderer)
{
_renderer = renderer ?? throw new ArgumentNullException("Renderer");
}
public override void OnPageStarted(Android.Webkit.WebView view, string url, Android.Graphics.Bitmap favicon)
{
base.OnPageStarted(view, url, favicon);
if (_renderer != null && _renderer.isMyCustomWebview)
{
DependencyService.Get<ILoadingIndicator>().Show();
var args = new WebNavigatingEventArgs(WebNavigationEvent.NewPage, new UrlWebViewSource { Url = url }, url);
_renderer.ElementController.SendNavigating(args);
}
}
public override void OnPageFinished(Android.Webkit.WebView view, string url)
{
base.OnPageFinished(view, url);
if (_renderer != null && _renderer.isMyCustomWebview)
{
DependencyService.Get<ILoadingIndicator>().Dismiss();
var source = new UrlWebViewSource { Url = url };
var args = new WebNavigatedEventArgs(WebNavigationEvent.NewPage, source, url, WebNavigationResult.Success);
_renderer.ElementController.SendNavigated(args);
}
}
}
}
}
更新:iOS 项目中的自定义渲染器:
[assembly: ExportRenderer(typeof(Xamarin.Forms.WebView), typeof(MyProject.iOS.WebViewRenderer))]
namespace MyProject.iOS
{
// Xamarin.Forms.Platform.iOS.WebViewRenderer
public class WebViewRenderer : ViewRenderer<WebView, WKWebView>
{
WKWebView wkWebView;
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (Control != null) return;
var config = new WKWebViewConfiguration();
wkWebView = new WKWebView(Frame, config) { NavigationDelegate = new MyNavigationDelegate() };
SetNativeControl(wkWebView);
}
}
public class MyNavigationDelegate : WKNavigationDelegate
{
public override void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
{
//get url here
var url = webView.Url;
// webView.LoadFileUrl(url, url);
}
}
}
更新:
以下是我在可移植项目中为 webview 设置源和基本 URL 的方法:
Here's how I'm setting the source and base url for the webview in the portable project:
var result = await client.PostAsync("/embedded/pay", content);
if (result.IsSuccessStatusCode)
{
var resp = await result.Content.ReadAsStringAsync();
var html = new HtmlWebViewSource
{
Html = resp,
BaseUrl = paymentGatewayUrl
};
//Adding Cookie
CookieContainer cookies = new CookieContainer();
var domain = new Uri(html.BaseUrl).Host;
var cookie = new Cookie
{
Secure = true,
Expired = false,
HttpOnly = false,
Name = "cookie",
Expires = DateTime.Now.AddDays(10),
Domain = domain,
Path = "/"
};
cookies.Add(new Uri(html.BaseUrl), cookie);
webView.Source = html;
}
推荐答案
你可以修改Custom Renderer的代码如下.
You could modify the code of Custom Renderer like following .
[assembly: ExportRenderer(typeof(WebView), typeof(MyWebViewRenderer))]
namespace xxx.iOS
{
public class MyWebViewRenderer : ViewRenderer<WebView, WKWebView>
{
WKWebView wkWebView;
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (Control != null) return;
var config = new WKWebViewConfiguration();
wkWebView = new WKWebView(Frame, config) { NavigationDelegate = new MyNavigationDelegate() };
SetNativeControl(wkWebView);
}
}
public class MyNavigationDelegate : WKNavigationDelegate
{
public override void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
{
//get url here
var url = webView.Url;
//webView.LoadFileUrl();
}
}
}
这篇关于在 Xamarin Forms 中实现自定义 Webview的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!