使用本地 css Xamarin 窗体设置外部网页的样式



我从后端获取一个字符串形式的外部页面 HTML 代码

并在 Xamarin 窗体应用的 Web 视图中显示它

现在我想设计它

我想知道最有效的方法是什么?

是否可以像使用 XAML 和共享资源设置 Xamarin 页面样式一样设置其样式?

到目前为止,我尝试在共享资源中引用 CSS 文件,但我发现它不起作用......

htmlData = "<link rel="stylesheet" type="text/css"href="Assets"Styles"style.css" />" + htmlData; 
htmlSource.Html = htmlData;
myWebView.Source = htmlSource;

更新

我最终为 Web 视图使用了自定义渲染器

适用于安卓,但不适用于IOS

这是我的渲染器的IOS实现

[assembly: ExportRenderer(typeof(CustomWebView), typeof(CustomWebViewRenderer))]
namespace XXX.iOS.Renderers
{
public class CustomWebViewRenderer : WkWebViewRenderer
{
WKUserContentController userController;
public CustomWebViewRenderer() : this(new WKWebViewConfiguration())
{
}
public CustomWebViewRenderer(WKWebViewConfiguration config) : base(config)
{
userController = config.UserContentController;
}
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
var customWebView = e.NewElement as CustomWebView;
if (e.NewElement != null)
{
string htmldata = customWebView.HTMLData;
htmldata = "<link rel="stylesheet" type="text/css" href="StyleSheet.css" />" + htmldata;
WkWebViewRenderer wkWebViewRenderer = new WkWebViewRenderer();
NSData data = NSData.FromString(htmldata);
wkWebViewRenderer.LoadData(data,"text/html", "UTF-8",new NSUrl(""));
}
}
}
}

注意:我不知道IOS代码发生了什么,因为我从未用母语编码过

我不知道这对你来说是否可行,但你可以在 HTML 字符串中注入实际的 CSS,然后分配HtmlSource

var css = ReadStringFromAsset("style.css");
htmlData = InjectCssInHtml(htmlData, css);
htmlSource.Html = htmlData;
myWebView.Source = htmlSource;

根据您对收到的HTML的控制程度,您有几个关于如何实现InjectCssInHtml

的选项

伪标记注释

如果更改 HTML 可行,则可以添加 HTML 注释作为 pdeudo 标记。这将使代码变得简单,但必须相应地编辑每个 HTML

<html>
<head>
<style>
<!-- CSS -->
</style>
...
</html>

然后,您的InjectCssInHtml变为

string InjectCssInHtml(string html, string css)
{
return html.Replace("<!-- CSS -->", css);
}

无需编辑 HTML

如果编辑 HTML 不可行,InjectCssInHtml会变得更加复杂。以下是第一个猜测,但我想你明白了

string InjectCssInHtml(string html, string css)
{
string codeToInject;
int indexToInject = 0;
if(ContainsStyleTag(html))
{
indexToInject = IndexOfStyleTagContent(html);
codeToInject = css;
}
else if(ContainsHeadTag(html))
{
indexToInject = IndexOfHeadTagContents(html);
codeToInject = $"<style>{css}</style>";
}
else
{
indexToInject = IndexOfHtmlTagContents(html);
codeToInject = $"<head><style>{css}</style></head>";
}
return html.Insert(indexToInject, codeToInject);
}

当然,这并不涵盖每种可能的情况,但我想你明白了。ìf-else'可以被抽象的工厂代际模式与战略行为模式相结合所取代。

string InjectCssInHtml(string html, string css)
{
ICssInjector injector = injectorFactory.CreateInjector(html);
return injector.InjectCss(html, css);
}

最新更新