Auto resize WebView to fit content
Firstly you should set the ListView's HasUnevenRows
to true, then I recommend
you to use Grid
to wrap your webView
and remove the HeightRequest
in XAML. You can refer to my 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>
For your Android renderer:
Do not use static identifier for _xwebView
and in LoadingFinished()
when we get the actual HeightRequest
, refresh the ViewCell
using ForceUpdateSize()
like:
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);
}
}
}
For iOS:
We also need to refresh the cell when the webView finished loading:
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();
}
}