【问题标题】:HTML mixed with XFormsHTML 与 XForms 混合
【发布时间】:2017-07-10 18:13:28
【问题描述】:

我正在开发一个应用程序,我正在尝试使用 HybridWebView("https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/custom-renderer/hybridwebview/") 加载一个 html 页面。

在我试图加载的 html 页面上,我有一个引导轮播控件 (https://v4-alpha.getbootstrap.com/components/carousel/#via-data-attributes)。问题是它不可见!除轮播外,所有其他元素都是可见的。如果我在我的 android 手机上加载 html 页面,它会完美运行。为什么它在 xamarin 中不起作用? xamarin 不支持 JQuery 吗?

我的 HTML

<html>

<style>
    .carousel-inner {
        height: 100%;
        background-size: cover;
        background-position: center;
        background-repeat: no-repeat;
    }
</style>

<h3>Hello World</h3>
<h3>Sup!</h3>

<div id="carouselExampleIndicators" class="carousel slide" data-ride="carousel" style="background-color: aqua">
    <ol class="carousel-indicators">
        <li data-target="#carouselExampleIndicators" data-slide-to="0" class="active"></li>
        <li data-target="#carouselExampleIndicators" data-slide-to="1"></li>
        <li data-target="#carouselExampleIndicators" data-slide-to="2"></li>
    </ol>
    <div class="carousel-inner" role="listbox">
        <div class="carousel-item active">
            <h1>First Slide</h1>
        </div>
        <div class="carousel-item">
            <h1>Second Slide</h1>
        </div>
        <div class="carousel-item">
            <h1>Third Slide</h1>
        </div>
    </div>
    <a class="carousel-control-prev" href="#carouselExampleIndicators" role="button" data-slide="prev">
        <span class="carousel-control-prev-icon" aria-hidden="true"></span>
        <span class="sr-only">Previous</span>
    </a>
    <a class="carousel-control-next" href="#carouselExampleIndicators" role="button" data-slide="next">
        <span class="carousel-control-next-icon" aria-hidden="true"></span>
        <span class="sr-only">Next</span>
    </a>
</div>


<script src="https://code.jquery.com/jquery-3.2.1.min.js"
        integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
        crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-migrate-3.0.0.min.js"
        integrity="sha256-JklDYODbg0X+8sPiKkcFURb5z7RvlNMIaE3RA2z97vw="
        crossorigin="anonymous"></script>


<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>

<script type="text/javascript">

    var $item = $('.carousel .item');
    var $wHeight = $(window).height();
    $item.eq(0).addClass('active');
    $item.height($wHeight);
    $item.addClass('full-screen');

    $('.carousel img').each(function () {
        var $src = $(this).attr('src');
        var $color = $(this).attr('data-color');
        $(this).parent().css({
            'background-image': 'url(' + $src + ')',
            'background-color': $color
        });
        $(this).remove();
    });

    $(window).on('resize', function () {
        $wHeight = $(window).height();
        $item.height($wHeight);
    });


    $('.carousel').carousel()

    function log(str)
    {
        $('#result').text($('#result').text() + " " + str);
    }

    function invokeCSCode(data) {
        try {
            log("Sending Data:" + data);
            invokeCSharpAction(data);
        }
        catch (err){
            log(err);
        }
    }
</script>

我的 Android HybridWebView 实现

public class HybridWebViewRenderer : ViewRenderer<HybridWebView, Android.Webkit.WebView>
{
    const string JavaScriptFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}";

    protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
    {
        base.OnElementChanged(e);

        if(Control == null)
        {
            var webView = new Android.Webkit.WebView(Forms.Context);
            webView.Settings.JavaScriptEnabled = true;
            webView.Settings.AllowFileAccess = true;
            webView.Settings.AllowFileAccessFromFileURLs = true;
            webView.Settings.AllowContentAccess = true;
            webView.SetWebChromeClient(new WebChromeClient());
            SetNativeControl(webView);
        }
        if(e.OldElement != null)
        {
            Control.RemoveJavascriptInterface("jsBridge");
            var hybridWebView = e.OldElement as HybridWebView;
            hybridWebView.Cleanup();
        }
        if(e.NewElement != null)
        {
            Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
            Control.LoadUrl(string.Format("file:///android_asset/Content/{0}", Element.Uri));
            InjectJS(JavaScriptFunction);
        }
    }

    void InjectJS(string script)
    {
        if (Control != null)
        {
            Control.LoadUrl(string.Format("javascript: {0}", script));
        }
    }
}

【问题讨论】:

    标签: twitter-bootstrap google-chrome xamarin webview xamarin.android


    【解决方案1】:

    我自己解决了这个问题。 我测试将其重写为普通的android应用程序,并注意到它仅在WebView元素是这样的顶部节点时才有效:

    <?xml version="1.0" encoding="utf-8"?>
    <WebView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/webview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
    

    我认为 xamarin 表单不会自动将 viewrender 元素放置在层次结构的顶部。 于是我在线查看了xamarin自己的webview实现,发现通过添加这行代码“webView.LayoutParameters = new global::Android.Widget.AbsoluteLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent, 0, 0);”到 webView 对象解决了这个问题。也对不起我平庸的英语。

    https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Platform.Android/Renderers/WebViewRenderer.cs

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-24
      • 2011-02-13
      • 2013-03-23
      • 1970-01-01
      相关资源
      最近更新 更多