質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.21%

xamarin.formsのWebViewを使った時のスケーリング?

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 2,771

otaota

score 30

前提・実現したいこと

WebViewを使って外部のHPを表示しようとしたときに、ページによっては実際の画面より大きく表示され、スクロールしないとページ全体が見えないことがあります。
一方、同じURLを
Device.OpenUri()
を使って表示したときにはちょうど横幅が収まるようにスケーリングされています。
WebViewを使ったときもDevice.OpenUri()を使ったときと同じ大きさで表示させたいたいと思っています。
アドバイスお願いします。

発生している問題・エラーメッセージ

表示上の問題で特にエラーがでているわけではありません。

該当のソースコード

[MainPage.cs]

using System;

using Xamarin.Forms;

namespace WebViewTest
{
    public class MainPage : ContentPage
    {
        public MainPage()
        {
            var url = "http://kyushujangara.co.jp";

            // Device.OpenUri
            var button1 = new Button
            {
                Text = "button1",
            };
            button1.Clicked += (sender, e) =>
            {
                Device.OpenUri(new Uri(url));
            };
            // WebView
            var button2 = new Button
            {
                Text = "button2",
            };
            button2.Clicked += (sender, e) =>
            {
                Navigation.PushAsync(new WebPage(url, (int)Width, (int)Height), true);
            };

            Content = new StackLayout
            {
                Children = {
                        button1,
                        button2,
                }
            };
        }
    }
}

[WebPage.cs]

using System;
using System.Diagnostics;

using Xamarin.Forms;

namespace WebViewTest
{
    public class WebPage : ContentPage
    {

        public WebPage(string url, int w, int h)
        {
            var webView = new WebView
            {
                Source = url,
//                WidthRequest = 640,
//                HeightRequest = 960,
            };

#if false
            var baseLayout = new AbsoluteLayout();
            var layout = new AbsoluteLayout()
            {
                WidthRequest = 640,
                HeightRequest = 960,
            };

            SizeChanged += (sender, e) =>
            {
                // ここが最後に実行される
                Debug.WriteLine("0 : " + Width + " X " + Height);
                layout.AnchorX = 0;
                layout.AnchorY = 0;
                layout.Scale = Width / layout.Width;
            };
            webView.SizeChanged += (sender, e) =>
            {
                Debug.WriteLine("W : " + webView.Width + " x " + webView.Height);
            };
            layout.SizeChanged += (sender, e) =>
            {
                Debug.WriteLine("L : " + layout.Width + " x " + layout.Height);
            };
            baseLayout.SizeChanged += (sender, e) =>
            {
                Debug.WriteLine("B : " + baseLayout.Width + " x " + baseLayout.Height);
            };

            layout.Children.Add(webView);
            baseLayout.Children.Add(layout);
            Content = baseLayout;
#else
            Content = webView;
#endif
        }
    }
}

試したこと

AnchorX,AnchorY,Scaleをいじれば、それっぽくなることは試したのですが、実際のページのサイズの取得の仕方がわからず、最適の値を求めることができません。

上記のソースの[WebPage.cs]の中の#if false 〜 #endifの部分はこちらの考えを元にやってみたのですが、こちらも期待したスケールにはなりませんでした。

補足情報(言語/FW/ツール等のバージョンなど)

Xamarin 6.2(build 1829)    
Mac Note Pro    
OS X Yosemite(10.10.5)

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

下記はAndroidの場合です。
カスタムレンダーでWebViewのViewPortをtrueにします。

using Xamarin.Forms;

[assembly: ExportRenderer(typeof(WebView), typeof(WebViewTest.Droid.WebViewRenderer))]
namespace WebViewTest.Droid
{
    public class WebViewRenderer : Xamarin.Forms.Platform.Android.WebViewRenderer
    {
        protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Xamarin.Forms.WebView> e)
        {
            base.OnElementChanged(e);
            Control.Settings.LoadWithOverviewMode = true;
            Control.Settings.UseWideViewPort = true;
        }
    }
}

iOSの場合(こちら動作未確認です)

using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(WebView), typeof(WebViewTest.iOS.WebViewRenderer))]

namespace WebViewTest.iOS
{
    public class WebViewRenderer : Xamarin.Forms.Platform.iOS.WebViewRenderer
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);
            ScalesPageToFit = true;
            ContentMode = UIKit.UIViewContentMode.ScaleAspectFit;
        }
    }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/21 17:54

    ありがとうございます。今ちょっと時間がないので週末に試してみます。

    キャンセル

  • 2017/04/23 21:04

    試したところAndroid/iPhoneともに期待する動作が確認できました。
    ありがとうございます。

    ちなみに、カスタムレンダラーという発想はなかったのですが、
    そこにたどり着いていたとしても、それぞれ何を設定すれば良いかわからなかったと思うのですが、
    それらはともに、Objective-C/Javaで書くときに設定するものでしょうか?

    キャンセル

  • 2017/04/24 11:52

    私自身がネイティブ開発をやらないのですが、おそらく必要な機能です
    カスタムレンダーはXamarin.Formsで共通APIとして提供されていないネイティブ機能をいじるためのものです
    そして、Xamarin.Formsでちょっとましなアプリを作ろうと考えると避けて通れない機能(Xamarin.Formsでは提供されているAPIがあまりにも少ない為)です

    今回やりたいこと(横幅が収まるようにスケーリング)を聞いた感じ、ViewPortの設定が出来れば良さそうということがわかったので、
    まずWebView自身にViewPortを設定する機能が無いか確認しました
    残念ながらWebViewにはそういった機能が無さそうでしたので、
    次にネイティブで同様の機能が無いか調査しました

    カスタムレンダーの一覧
    https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/custom-renderer/renderers/

    上記URLの一覧を見るとわかりますが、Xamarin.FormsのWebViewはネイティブでそれぞれ
    WebView(Android)、UIWebView(iOS)に対応することがわかります

    ネイティブのWebView、UIWebViewのAPIリファレンスを参照するか、
    UIWebViewとViewPortなどでググれば良い感じです

    キャンセル

  • 2017/04/24 17:25

    回答ありがとうござます。

    ちょっと、追加の質問の意図が分かりにくかったですね。

    カスタムレンダラーで機能拡張できることはある程度理解しているつもりなんですが、今回は自分自身がスケールの調整で解決できると思い込んでいたため、カスタムレンダラーで解決しようという発想がまったくなかったのと、あと、自分はUnity上がりでJavaやObjective-Cでのプログラミング経験がほぼほぼなかったため、万が一、カスタムレンダラーで解決すると分かっていたとしても、具体的にそれぞれでどういう記述をすれば良いかというのがわからなかっただろうなということで、今回教えていただいた答えにたどり着くためには、Xamarinを勉強するだけでたどり着くものなのか、JavaやObjective-Cでの解決策が分かっていたからたどり着いたのか?ということを確認したくて質問しました。

    答えから逆にたどると、やはり、Java/Objective-Cでの解決策があり、それをXamarinでの書き方で実装したということがわかりました。

    非常に参考になりました。ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.21%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる