1

Please see my comments below before marking this as an exact duplicate of another question that is not looking for the same things.

So far I have already tried loading locally like this:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    xmlns:local="clr-namespace:Japanese;assembly=Test" 
    x:Class="Test.HelpCards" 
    x:Name="HelpCards" 
    Title="Help ▹ Cards Tab">
    <ContentPage.Content>
        <WebView x:Name="Browser" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" />
    </ContentPage.Content>
</ContentPage>

public HelpCards()
{
    InitializeComponent();
    var htmlSource = new HtmlWebViewSource();
    htmlSource.Html = @"<html><body>
    <h1>ABC</h1>
    <p>DEF</p>
    </body></html>";
    Browser.Source = htmlSource;
}

Now I would like to instead do the same but store the HTML in a file and have CSS (different for Android and iOS). I'd like to find a way to load this into the Browser.

Does anyone have any examples of how this can be done. In particular it's important for me to have just the one HTML file in my common project and then CSS files for Android and iOS in those two projects.

Note that this is not an exact duplicate of

Loading Local HTML with WebView Xamarin Forms

The only thing duplicate about it is that the title is similar.

That question states:

  • "only needs to be done through Android so there is no worries about about IOS and Windows."
  • That question also does not address a common HTML
  • That question also does not mention anything about CSS

I have had to close and reopen this question as it was falsely marked as an exact duplicate by a person who I assume didn't look very closely. Please do not mark as an exact duplicate.

Update: Here's what I have as a problem right now

NSBundle.MainBundle.BundlePath; is this:

"/Users/alan/Library/Developer/CoreSimulator/Devices/2184643E-9C57-4CFD-A7F9-A55CBC983402/data/Containers/Bundle/Application/9C950717-4E9C-4494-BF63-DC3AC3EDDE8C/Japanese.iOS.app"

My HTML is this:

<!DOCTYPE html>
<html>
    <head>
       <meta charset="utf-8" />
       <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        Hello again
        <h1>hihi</h1>
    </body>
</html>

My style.css file is in the Resources folder of Japanese.iOS and is this:

body {
    background-color: lightblue;
}

h1 {
    color: navy;
    margin-left: 20px;
    font-size: 99px;
}
Alan2
  • 23,493
  • 79
  • 256
  • 450
  • PCL projects do not contain assets/bundle resources/etc.. unless they are an assembly-based embedded resource, you can always embed an HTML file and load it into a string and assign that to your `WebView`, as far as platform-dependent CSS, load it into a string based upon platform dependent methods and inject the CSS into your HTML string before apply the string to your WebView – SushiHangover Oct 25 '17 at 18:03

1 Answers1

5
  1. To have shared html files - you can register them as embedded resources in your shared PCL project. Make sure to refer your platform-specific css files by name. Sample html file would look like:

    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" href="styles.css">
    </head>
    
  2. Add android-specific css file as an asset to android project

    android asset

  3. Add iOS-specific css file as a resource to iOS project

    ios resource

  4. Introduce an interface to shared project - for accessing path for platform-specific assets/resources.

    public interface IBaseUrl { string Get(); }
    
  5. Implement the same for android

    [assembly: Dependency(typeof(AppNamespace.Droid.BaseUrl))]
    namespace AppNamespace.Droid
    {
        public class BaseUrl : IBaseUrl
        {
            public string Get()
            {
                return "file:///android_asset/";
            }
        }
    }
    
  6. And for iOS

    [assembly: Dependency(typeof(AppNamespace.iOS.BaseUrl))]
    namespace AppNamespace.iOS
    {
        public class BaseUrl : IBaseUrl
        {
            public string Get()
            {
                return NSBundle.MainBundle.BundlePath;
            }
        }
    }
    
  7. Now you can setup your WebView to use shared html files, while using platform-specific css - which is specified through BaseUrl.

    var assembly = typeof(AppNamespace.App).GetTypeInfo().Assembly;
    var stream = assembly.GetManifestResourceStream("AppNamespace.Common.html");
    string html = string.Empty;
    using (var reader = new System.IO.StreamReader(stream))
    {
        html = reader.ReadToEnd();
    }
    
    var source = new HtmlWebViewSource()
    {
        BaseUrl = DependencyService.Get<IBaseUrl>().Get(),
        Html = html
    };
    
    webView.Source = source;
    
Sharada Gururaj
  • 13,471
  • 1
  • 22
  • 50
  • Thanks, I will try this out and let you know if I have any questions. – Alan2 Oct 26 '17 at 03:46
  • I have tried your answer but it seems like the css files is not included in the resource bundle or it is then it's not being called. I also noticed the same in the example: https://developer.xamarin.com/samples/xamarin-forms/WorkingWithWebview/ Whatever changes I made to the default.css here are not reflected in what I see. I would appreciate if you could try this and let me know if you see the same thing. Note that I only tried iOS so far. Thanks – Alan2 Oct 26 '17 at 10:50
  • I updated the question to show the problem I am having. – Alan2 Oct 26 '17 at 10:57
  • 2
    Tested it - it is working as expected. Could there be a name mismatch issue? You can access the code at this [Github link](https://github.com/shads-labs/SharedHtmlWebView) – Sharada Gururaj Oct 26 '17 at 11:54
  • Rebuild All fixed the problem. Thanks – Alan2 Oct 26 '17 at 12:37