Phoneswapshop
Phoneswapshop

Reputation: 1397

How to load a local html file in a xamarin forms webview

I am trying to load a html file that is in the same path as class i'm working with Via a web view in xamarin forms when I run the app I get a white screen and nothing loads here's my code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;

namespace App.Plan
{
    public partial class Tornado : ContentPage
    {
        public Tornado()
        {
            InitializeComponent();
            var browser = new WebView
            {
                Source = "local.html"
};
    }
    }
}

Upvotes: 2

Views: 9818

Answers (3)

kiddailey
kiddailey

Reputation: 3664

I realize this is old, but the documentation is maybe not entirely clear when it comes to local files so I thought I'd share my thoughts. Hopefully it's helpful to anyone who stumbles here.

The documentation states:

To display local content using a WebView, you'll need to open the HTML file like any other, then load the contents as a string into the Html property of an HtmlWebViewSource.

The key thing to note is that the WebView's Source property is ONLY for external URLs or HtmlWebViewSource. You cannot put a local URL in the Source property. The phrasing "you'll need to open the HTML file like any other" means (as it states shortly after) that you need to load the contents of the file from disk into a variable using a full file path, not URL.

The question then becomes "What about links to other local files?" That's where the BaseUrl property of HtmlWebViewSource comes into play. The documentation addresses this by stating the following:

Although the first page has been loaded, the WebView has no knowledge of where the HTML came from. That is a problem when dealing with pages that reference local resources. Examples of when that might happen include when local pages link to each other, a page makes use of a separate JavaScript file, or a page links to a CSS stylesheet.

In other words, any links to local resources in your HTML will be prepended with the BaseUrl by the Webview automatically.

To sum things up

Create the IBaseUrl Interface in your shared project

public interface IBaseUrl { 
    string Get(); 
}

Create the platform-specific implementations of IBaseUrl in each platform project

iOS:

[assembly: Dependency (typeof (BaseUrl_iOS))]
namespace WorkingWithWebview.iOS
{
  public class BaseUrl_iOS : IBaseUrl
  {
    public string Get()
    {
      return NSBundle.MainBundle.BundlePath;
    }
  }
}

Android

[assembly: Dependency (typeof(BaseUrl_Android))]
namespace WorkingWithWebview.Android
{
  public class BaseUrl_Android : IBaseUrl
  {
    public string Get()
    {
      return "file:///android_asset/";
    }
  }
}

UWP

[assembly: Dependency(typeof(BaseUrl))]
namespace WorkingWithWebview.UWP
{
    public class BaseUrl : IBaseUrl
    {
        public string Get()
        {
            return "ms-appx-web:///";
        }
    }
}

Make sure your HTML files are in the appropriate folders and have the proper Build Action

  • iOS: Resources, build action: "BundleResource"
  • Android: Assets, build action: "AndroidAsset"
  • UWP: project root, build action: "content"

Make sure the WebView has a height and width request or it may not render:

It may be necessary to set the WidthRequest and HeightRequest properties of the WebView to see the HTML content, depending upon the layout the WebView is a child of. For example, this is required in a StackLayout.

Once that setup is done, you can put it into action in your shared project. Here's a simplified example:

// Use DI function to get the BaseUrl for the platform
var baseUrl = DependencyService.Get<IBaseUrl>().Get();

// You could append subfolders here if you don't 
// want all the HTML files mixed with other resources:
// var baseUrl = System.IO.Path.Combine(DependencyService.Get<IBaseUrl>().Get(), "subfolder");

// Define the location of your initial HTML page using the base url
var initialHtmlPath = System.IO.Path.Combine(baseUrl, "index.html");

// Create the viewsource, loading the first HTML file as a string
var localHtmlViewSource = new HtmlWebViewSource();
localHtmlViewSource.BaseUrl = baseUrl;
localHtmlViewSource.Html = System.IO.File.ReadAllText(initialHtmlPath);

// Set the webview to use the local source
HelpWebView.Source = localHtmlViewSource;

Upvotes: 7

Max CHien
Max CHien

Reputation: 143

Here is official sample in github

WorkingWithWebview

tabs.Children.Add (new LocalHtml {Title = "Local" });
tabs.Children.Add (new LocalHtmlBaseUrl {Title = "BaseUrl" });
tabs.Children.Add (new WebPage { Title = "Web Page"});
tabs.Children.Add (new WebAppPage {Title ="External"});

Second tab may help.

Upvotes: 0

Mario Galv&#225;n
Mario Galv&#225;n

Reputation: 4032

Xamarin has docs in relation to this:

https://developer.xamarin.com/guides/xamarin-forms/user-interface/webview/

var browser = new WebView();
var htmlSource = new HtmlWebViewSource();
htmlSource.Html = @"<html><body>
  <h1>Xamarin.Forms</h1>
  <p>Welcome to WebView.</p>
  </body></html>";
browser.Source = htmlSource;

Upvotes: 1

Related Questions