zoukankan      html  css  js  c++  java
  • Xamarin Forms中WebView的自适应高度

    在Xamarin.Forms中,WebView如果嵌套在StackLayout和RelativeLayout中必须要设置HeightRequest和WidthRequest属性才会进行渲染。可是在实际项目中往往WebView内容是不固定的,就造成了设置了HeightRequest和WidthRequest后显示效果不理想,不是高了就是短了,很影响用户体验,那么就必须要自适应网页的高度才行。

    首先在共享库中的添加XamWebView类:

    public class XamWebView: WebView {}
    

    然后使用它:

    var webview= new XamWebView();
     
    webview.HorizontalOptions = LayoutOptions.Fill;
    webview.VerticalOptions = LayoutOptions.StartAndExpand;
    //给个默认的高度和宽度
    webview.WidthRequest = 300;
    webview.HeightRequest = 300;
     
    webview.Source = "https://www.cnblogs.com/";
    

    然后在IOS中,你需要使用自定义的委托:

    [assembly: ExportRenderer (typeof(XamWebView), typeof(XamWebViewRenderer))]
    namespace Core.iOS
    {
        public class XamWebViewRenderer : WebViewRenderer
        {      
            protected override void OnElementChanged (VisualElementChangedEventArgs e)
            {
                base.OnElementChanged (e);            
                Delegate = new XamUIWebViewDelegate (this);           
            }
        }
    }
    

    然后用异步和小延迟重写LoadFinished以获取整个ContentSize.Height(如果内容较大,即使加载完成后也需要一些时间才能呈现)

    public class XamUIWebViewDelegate : UIWebViewDelegate
    {
        XamWebViewRenderer webViewRenderer;
     
        public XamUIWebViewDelegate (XamWebViewRenderer _webViewRenderer = null)
        {
            webViewRenderer = _webViewRenderer ?? new XamWebViewRenderer ();
        }     
     
        public override async void LoadingFinished (UIWebView webView)
        {
            var wv = webViewRenderer.Element as XamWebView;
            if (wv != null) {
                await System.Threading.Tasks.Task.Delay (100); // 这里的时间可以调整
                wv.HeightRequest = (double)webView.ScrollView.ContentSize.Height;
            }            
        }
    }
    

    在Android中,您需要使用自定义的Android.Webkit.WebViewClient:

    using WebView = Android.Webkit.WebView;
    [assembly: ExportRenderer (typeof(XamWebView), typeof(XamWebViewRenderer))]
    namespace Core.Droid
    {
        
        public class XamWebViewRenderer : WebViewRenderer
        {
            static XamWebView _xwebView = null;
            WebView _webView;
    
            public XamWebViewRenderer(Context context) : base(context)
            {
    
            }
            class XamWebViewClient : Android.Webkit.WebViewClient
            {
                public override async void OnPageFinished(WebView view, string url)
                {
                    if (_xwebView != null)
                    {
                        int i = 10;
                        while (view.ContentHeight == 0 && i-- > 0)
                            await System.Threading.Tasks.Task.Delay(100);// 这里的时间可以调整
                        _xwebView.HeightRequest = view.ContentHeight;
                    }
                }
            }
            protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
            {
                base.OnElementChanged(e);
                _xwebView = e.NewElement as XamWebView;
                _webView = Control;
    
                if (e.OldElement == null)
                {
                    _webView.SetWebViewClient(new XamWebViewClient());
                }
    
            }
        }
    }
    

    放一张Android截图:

  • 相关阅读:
    一些你可能用到的代码
    iOS 键盘下去的方法
    iOS设计模式汇总
    随笔
    Spring cloud config 分布式配置中心 (三) 总结
    Spring cloud config 分布式配置中心(二) 客户端
    Spring cloud config 分布式配置中心(一) 服务端
    jdbcUrl is required with driverClassName spring boot 2.0版本
    JpaRepository接口找不到 spring boot 项目
    解决IntelliJ “Initialization failed for 'https://start.spring.io'
  • 原文地址:https://www.cnblogs.com/ourozts/p/8608227.html
Copyright © 2011-2022 走看看