我正在开发一个以WebView形式显示帖子的Xamarin.Forms PCL项目,因此我添加了可点击的内容,例如hashtags。
我遇到的问题是WebView无法调整其内容的大小。 WebView不加载实际站点我使用
将HTML绑定到ListView中的每个帖子 "<html><p>" + body + "</p></html>"
我尝试研究自定义渲染器,然后跟着this tutorial,最后得到以下代码
对于Android我使用
#pragma warning disable CS0618 // Type or member is obsolete
public class CustomWebViewAndroid : WebViewRenderer
{
static CustomWebView _xwebView = null;
WebView _webView;
class ExtendedWebViewClient : Android.Webkit.WebViewClient
{
public override async void OnPageFinished (WebView view, string url)
{
if (_xwebView != null) {
int i = 10;
while (view.ContentHeight == 0 && i-- > 0) // wait here till content is rendered
await System.Threading.Tasks.Task.Delay (100);
_xwebView.HeightRequest = view.ContentHeight;
}
base.OnPageFinished (view, url);
}
}
protected override void OnElementChanged (ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged (e);
_xwebView = e.NewElement as CustomWebView;
_webView = Control;
if (e.OldElement == null) {
_webView.SetWebViewClient (new ExtendedWebViewClient ());
}
}
}
适用于iOS
public class CustomWebViewiOS : WebViewRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
Delegate = new CustomWebViewDelegate(this);
}
}
public class CustomWebViewDelegate : UIWebViewDelegate
{
CustomWebViewiOS webViewRenderer;
public CustomWebViewDelegate(CustomWebViewiOS _webViewRenderer = null)
{
webViewRenderer = _webViewRenderer ?? new CustomWebViewiOS();
}
public override async void LoadingFinished(UIWebView webView)
{
var wv = webViewRenderer.Element as CustomWebView;
if (wv != null)
{
await System.Threading.Tasks.Task.Delay(100); // wait here till content is rendered
wv.HeightRequest = (double)webView.ScrollView.ContentSize.Height;
}
}
}
然后将其应用于XAML中
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<local:CustomWebView HeightRequest="20" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<local:CustomWebView.Source>
<HtmlWebViewSource Html="{Binding HtmlContent}"/>
</local:CustomWebView.Source>
</local:CustomWebView>
</StackLayout>
在Android上它会剪掉帖子的一半。
在iOS上,它没有正确分隔帖子并切断其上方的时间戳。我的猜测是ViewCell的高度调整到内容,但没有考虑其他帖子。同样对于iOS,如果文本需要两行,则需要滚动查看其余部分。
答案 0 :(得分:4)
首先,你应该将ListView的HasUnevenRows
设置为true,然后我推荐
您可以使用Grid
打包webView
并删除XAML中的HeightRequest
。你可以参考我的XAML:
<local:MyListView x:Name="MyListView" HasUnevenRows="True">
<local:MyListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<local:AutoWebView>
<local:AutoWebView.Source>
<HtmlWebViewSource Html="{Binding}"/>
</local:AutoWebView.Source>
</local:AutoWebView>
</Grid>
</ViewCell>
</DataTemplate>
</local:MyListView.ItemTemplate>
</local:MyListView>
当我们获得实际_xwebView
时,请不要在LoadingFinished()
和HeightRequest
中使用静态标识符,请使用ViewCell
刷新ForceUpdateSize()
,如下所示:
public class MyWebViewAndroidRenderer : WebViewRenderer
{
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
Control.SetWebViewClient(new ExtendedWebViewClient(Element as AutoWebView));
}
class ExtendedWebViewClient : Android.Webkit.WebViewClient
{
AutoWebView xwebView;
public ExtendedWebViewClient(AutoWebView webView)
{
xwebView = webView;
}
async public override void OnPageFinished(Android.Webkit.WebView view, string url)
{
if (xwebView != null)
{
int i = 10;
while (view.ContentHeight == 0 && i-- > 0) // wait here till content is rendered
await System.Threading.Tasks.Task.Delay(100);
xwebView.HeightRequest = view.ContentHeight;
// Here use parent to find the ViewCell, you can adjust the number of parents depending on your XAML
(xwebView.Parent.Parent as ViewCell).ForceUpdateSize();
}
base.OnPageFinished(view, url);
}
}
}
我们还需要在webView完成加载时刷新单元格:
public override void LoadingFinished(UIWebView webView)
{
var wv = webViewRenderer.Element as AutoWebView;
if (wv.HeightRequest < 0)
{
wv.HeightRequest = (double)webView.ScrollView.ContentSize.Height;
(wv.Parent.Parent as ViewCell).ForceUpdateSize();
}
}
答案 1 :(得分:0)
要显示 HTML 内容,您可以使用它,它对我来说很有吸引力,我们不需要使用渲染器来适应内容大小。
<Label BackgroundColor="White" Text="{Binding description}" TextType="Html"/>