この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
1 Webビューとは
Xamarin.Formsで提供されているWebViewを使用すると、URLを指定したり、ローカルに作成したWebページなどを表示することができます。
Xamarin Developers Guide 「Working with WebView」
元々、各プラットフォームには、Webページを表示するブラウザベースのコントロールが用意されています。iOSでは、UIWebView、Androidでは、WebView、そして、WindowsPhoneではWebBrowserがそれにあたります。 そして、Xamarin.Formsでは、これらを共通コードから利用できるようにしています。
2 Webページの表示
WebViewのSourceプロパティにURLを指定することで、Webページを表示することができます。
App1.cpp
public class App : Application {
public App() {
MainPage = new MyPage();
}
}
class MyPage : ContentPage {
public MyPage() {
// iOS の場合のみ、ステータスバーに重ならないように上に余白をとる
Padding = new Thickness (0,Device.OnPlatform(20, 0, 0),0,0);
// ページの唯一のコントロールとしてWebViewを配置する
Content = new WebView {
Source = "https://dev.classmethod.jp/" //表示するURLの指定
};
}
}
Android | iOS | Windows Phone |
![]() |
![]() |
![]() |
なお、iOS9以降では、ATS対応が必要です。下の図は、iOSプロジェクトのinfo.plist に「ATS を無効にする (非推奨)」という記述を追加した様子です。 ATSの扱いについては、下記をご参照ください。
[iOS 9] iOS 9 で追加された App Transport Security の概要
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
3 HTMLの表示
HTMLを表示させたい場合は、SourceプロパティにHtmlWebViewSourceオブジェクトを指定します。
public class App : Application {
public App() {
MainPage = new MyPage();
}
}
class MyPage : ContentPage {
public MyPage() {
// iOS の場合のみ、ステータスバーに重ならないように上に余白をとる
Padding = new Thickness (0,Device.OnPlatform(20, 0, 0),0,0);
var source = new HtmlWebViewSource {
Html = "<meta charset='UTF-8'><h1>Developers.IO</h1>AWS/iOS技術者の必読メディア"
};
// ページの唯一のコントロールとしてWebViewを配置する
Content = new WebView {
Source = source //HTMLを指定
};
}
}
Android | iOS | Windows Phone |
![]() |
![]() |
![]() |
HTML内からCSSや画像などの外部ファイルを指定したい場合は、基礎となるURL(プロパティBaseUrl)の指定が必要になります。
ディレクトリ構成は、ターゲットごと違うため、「ターゲット依存コード」としてこれを実装します。
参考:Xamarin.Forms トースト(DependencyService)
まずは、HTMLで、スタイルシートと画像を指定してみます。
public class App : Application {
public App() {
MainPage = new MyPage();
}
}
class MyPage : ContentPage {
public MyPage() {
// iOS の場合のみ、ステータスバーに重ならないように上に余白をとる
Padding = new Thickness (0,Device.OnPlatform(20, 0, 0),0,0);
var source = new HtmlWebViewSource {
Html = "<html><head><meta charset='UTF-8'><link rel='stylesheet' href='my.css'></head><body><h1>Developers.IO</h1><img src='Images/classmethod.png'><br>AWS/iOS技術者の必読メディア</body></html>"
};
// ページの唯一のコントロールとしてWebViewを配置する
Content = new WebView {
Source = source //HTMLを指定
};
}
}
my.css
body{
font-size:20px;
font-family:bold;
text-shadow: 0 1px 0 #ccc,
0 2px 0 #c9c9c9,
0 3px 0 #bbb,
0 4px 0 #b9b9b9,
0 5px 0 #aaa,
0 6px 1px rgba(0,0,0,.1),
0 0 5px rgba(0,0,0,.1),
0 1px 3px rgba(0,0,0,.3),
0 3px 5px rgba(0,0,0,.2),
0 5px 10px rgba(0,0,0,.25),
0 10px 10px rgba(0,0,0,.2),
0 20px 20px rgba(0,0,0,.15);
}
h1 {
font-size:50px;
}
当然ですが、スタイルシートと画像は適用されません。
Android | iOS | Windows Phone |
![]() |
![]() |
![]() |
そこで、HtmlWebViewSourceのBaseUrlを設定してみます。作業としては、ディレクトリ取得のメソッドをインターフェースとして定義し、それをDependencyService経由で使用します。
IBaseUrl.cs
//共通インターフェース
public interface IBaseUrl{
string Get();
}
App.cs
var source = new HtmlWebViewSource{
Html = " //・・・省略・・・
//基礎となるURLを指定する
BaseUrl = DependencyService.Get<IBaseUrl>().Get()
};
続いて、ターゲットごとにインターフェースの実装を行います。
(1) Androidの場合
Androidでは、生ファイル (raw asset files) を格納するためにAssetsフォルダを使用します。
Assetsフォルダに保存されたファイルは、そのままの形で.apkファイルに含まれ、ファイルシステムにアクセスするのと同様に、file:///android_asset/でアクセスできます。
そこで対象となるファイルを図のように配置して、次のようにインターフェースを実装します。
“App1.Android
using App1.Droid;
using Xamarin.Forms;
[assembly: Dependency(typeof(BaseUrl))]
namespace App1.Droid {
public class BaseUrl : IBaseUrl {
public string Get() {
return "file:///android_asset/";
}
}
}
スタイルシートと画像のパスが成立して、適用されていることを確認できます。
(2) iOSの場合
iOSにおいては、NSBundle.MainBundle.BundlePathから、ルート及びResourceの下にあるファイルにアクセスできます。
今回は、Contentというフォルダを作成しその中にリソースを置いてみました。
インターフェースの実装は、次のようになります。
App1.iOS BaseUrl.cs
[assembly:Dependency(typeof(BaseUrl))]
namespace App1.iOS {
class BaseUrl:IBaseUrl {
public string Get(){
return NSBundle.MainBundle.BundlePath+"/Content";
}
}
}
実行結果は、次のとおりです。当初、バグのためレンダラー拡張によりLoadHtmlStringを修正する必要があるとドキュメントに記載されていたのですが、現在は問題なくなっています。
(3) WindowsPhoneの場合
WindowsPhoneの場合、カレントフォルダにそのままアクセスできるので、ファイルの配置及び、インターフェースの実装は、下記のようになります。
App1.iOS BaseUrl.cs
using App1.WinPhone;
using Xamarin.Forms;
[assembly:Dependency(typeof(BaseUrl))]
namespace App1.WinPhone {
class BaseUrl : IBaseUrl {
public string Get() {
return "";
}
}
}
ちょっとスタイルの扱いが違ってるようですが、一応実行できてます。なお、ドキュメントにはWindowsPhone8.1や10では、動作できないような記述があったのですが、WindowsPhone10のシュミレータでは問題を確認できませんでした。
4 ナビゲーション及びイベント
ナビゲーションには、次の機能が利用可能です。
GoForward() | 進む |
GoBack() | 戻る |
CanGoForward | 「進む」ことが可能かどうかのフラグ |
CanGoBack | 「戻る」ことが可能かどうかのフラグ |
また、イベントとしては、次のものが利用可能です。
Navigating | ページのロードが開始した時 |
Navigated | ページのロードが完了した時 |
ナビゲーション及びイベントを処理して、サンプルとして簡単なブラウザを作成してみました。
Android | iOS | Windows Phone |
![]() |
![]() |
![]() |
書いたコードは、下記で全てです。
App.cs
public class App : Application {
public App() {
MainPage = new MyPage();
}
}
class MyPage : ContentPage {
public MyPage() {
// iOS の場合のみ、ステータスバーに重ならないように上に余白をとる
Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0);
var webView = new WebView() {
Source = "https://dev.classmethod.jp/", //起動時に表示するURLの指定
VerticalOptions = LayoutOptions.FillAndExpand // ナビゲーション部分以外は、全部WebViewのエリアとする
};
//「戻る」ボタン
var back = new Button {
Text = " <<",
IsEnabled = false // デフォルトで無効
};
back.Clicked += (s, e) => { // ボタンが押された時の処理
webView.GoBack(); // 戻る
};
//「進む」ボタン
var forword = new Button {
Text = ">>",
IsEnabled = false // デフォルトで無効
};
forword.Clicked += (s, e) => { // ボタンが押された時の処理
webView.GoForward(); // 進む
};
// 検索バー
var entry = new Entry {
HorizontalOptions = LayoutOptions.FillAndExpand
};
// 検索バーへの入力が完了した時
entry.Completed += (s, e) => {
webView.Source = entry.Text;//入力されたURLへジャンプする
};
// 上段のナビゲーション部分
var toolbar = new StackLayout {
Orientation = StackOrientation.Horizontal,
Children = {
back,forword,entry // 「戻る」ボタン、「進む」ボタン、検索バーを横に配置する
}
};
Content = new StackLayout() {
Children = { toolbar,webView} // ナビゲーション部分とWebViewを縦に配置する
};
// ロード完了時のイベント処理
webView.Navigated += (s, e) => {
back.IsEnabled = webView.CanGoBack; // CanGoBack==true の時、「戻る」ボタンを有効にする
forword.IsEnabled = webView.CanGoForward;// CanGoForward==true の時、「 進む」ボタンを有効にする
};
}
}
5 まとめ
今回は、Xamarin.FormsのWebViewについて、その機能を一通り紹介しました。
Xamarin.Formsの誕生当初、このWebViewは、非常に機能が乏しく、いろいろとレンダラー拡張しないと使えないという印象がありましたが、最近では、かなり拡充されてきて、この悪いイメージも払拭されつつあると思います。
6 参考資料
この辺でXamarin導入による 効果と限界をしっかり把握してみよう MVP Community Camp 2015
Xamarin記事一覧(SAPPOROWORKSの覚書)