【问题标题】:Styling an external webpage with local css Xamarin forms使用本地 css Xamarin 表单样式化外部网页
【发布时间】:2020-05-13 19:40:30
【问题描述】:

我从后端获取外部页面 HTML 代码作为字符串

并在 Xamarin 表单应用程序的 Web 视图中显示它

现在我想给它设置样式

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

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

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

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

更新

我最终为 Webview 使用了自定义渲染器

适用于 Android 但不适用于 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 代码发生了什么,因为我从来没有用母语编写过代码

【问题讨论】:

    标签: css xamarin.forms webview


    【解决方案1】:

    我不知道这对你是否可行,但你可以在 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);
    
    }
    

    【讨论】:

    • 感谢您的回答,我会试试看。但我刚刚用我目前的方法更新了我的问题,欢迎任何反馈
    • 我最终尝试了您的答案。它奏效了。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 2023-04-10
    • 2014-07-15
    • 1970-01-01
    • 2021-05-15
    • 2015-04-12
    • 1970-01-01
    • 2013-09-27
    • 1970-01-01
    相关资源
    最近更新 更多