如何解决如何检测滚动到底部的webview? WKWebViewRenderer 中的代码
我想知道用户何时结束在显示条款和条件的 Web 视图上滚动以仅在用户阅读此内容时显示“接受”按钮。
<StackLayout Spacing="0" BackgroundColor="{StaticResource WhiteColor}">
<CustomView:HeaderView VerticalOptions="Start" LeftimageSource="{Binding Leftimage}" RightimageSource="{Binding Rightimage}" LeftCommand="{Binding LeftClickCommand}" RightCommand="{Binding RightClickCommand}" HeaderText="{Binding ScreenTitle}" PrevText="{Localize:ETranslate PrevText}" />
<WebView Source="{Binding Html,Converter={StaticResource HtmlSourceConverter}}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
</StackLayout>
public class HtmlSourceConverter : IValueConverter
{
public object Convert(object value,Type targettype,object parameter,CultureInfo culture)
{
var html = new HtmlWebViewSource();
if (value != null)
{
html.Html = value.ToString();
}
return html;
}
public object ConvertBack(object value,CultureInfo culture)
{
throw new NotImplementedException();
}
}
我尝试使用 Renderer 来实现这一点,但在 iOS 中 WkWebVieWrenderer 没有 WebVieWrenderer 中可用的 Scrolled() 方法。
有没有办法在 Xamarin.Forms 中实现这一点?
解决方法
WKWebView 里面有一个属性 ScrollView
,所以我们可以用它覆盖 Delegate。
WKWebViewRenderer 中的代码
[assembly: ExportRenderer(typeof(WebView),typeof(MyRenderer))]
namespace FormsA.iOS
{
public class MyDelegate : UIScrollViewDelegate
{
public override void Scrolled(UIScrollView scrollView)
{
if(scrollView.ContentOffset.Y >= scrollView.ContentSize.Height - scrollView.Frame.Size.Height)
{
//here rearch bottom
}
else if(scrollView.ContentOffset.Y < scrollView.ContentSize.Height)
{
}
}
}
public class MyRenderer: WkWebViewRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
this.ScrollView.Delegate = new MyDelegate();
}
}
}
它在我这边工作得很好,请参阅https://stackoverflow.com/a/52872317/8187800。
,我也有适用于 Android 的解决方案。这是完整的解决方案,希望这可能对正在寻找相同解决方案的人有所帮助!
MyPage.xaml
<webview:ScrollWebView x:Name="webView" Source="{Binding Html,Converter={StaticResource HtmlSourceConverter}}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" IsBottomReached="{Binding IsShowAgreeButton}"/>
ScrollWebView 控件
public class ScrollWebView : WebView
{
public static BindableProperty IsBottomReachedProperty =
BindableProperty.Create(nameof(IsBottomReached),typeof(bool),typeof(ScrollWebView),default(bool),BindingMode.TwoWay,propertyChanged: null);
public bool IsBottomReached
{
get
{
return (bool)GetValue(IsBottomReachedProperty);
}
set
{
SetValue(IsBottomReachedProperty,value);
}
}
}
Android:ScrollWebViewRenderer
[assembly: Xamarin.Forms.ExportRenderer(typeof(ScrollWebView),typeof(ScrollWebViewRenderer))]
namespace MyApp.Droid
{
public class ScrollWebViewRenderer : WebViewRenderer
{
public static ScrollWebView view = null;
public ScrollWebViewRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
view = (ScrollWebView)Element;
if (Control != null)
{
Control.ScrollChange += Control_ScrollChange;
}
}
private void Control_ScrollChange(object sender,ScrollChangeEventArgs e)
{
var nativeWebView = e.V as global::Android.Webkit.WebView;
int height = (int)Math.Floor(nativeWebView.ContentHeight * nativeWebView.Scale);
int webViewheight = nativeWebView.Height;
int cutOff = height - webViewheight;
if (e.ScrollY >= cutOff)
{
view.IsBottomReached = true;
System.Diagnostics.Debug.WriteLine("Bottom Reached");
}
else
{
view.IsBottomReached = false;
}
}
}
}
iOS:ScrollWebViewRenderer
[assembly: ExportRenderer(typeof(ScrollWebView),typeof(ScrollWebViewRenderer))]
namespace MyApp.iOS.RendererClasses
{
public class ScrollWebViewRenderer : WkWebViewRenderer
{
public static ScrollWebView view = null;
public ScrollWebViewRenderer() { }
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
view = (ScrollWebView)Element;
MyDelegate myDel = new MyDelegate();
myDel.ProcessCompleted += MyDel_ProcessCompleted;
this.ScrollView.Delegate = myDel;
}
private void MyDel_ProcessCompleted(object sender,bool isScrolledToBottom)
{
view.IsBottomReached = isScrolledToBottom;
}
}
public class MyDelegate : UIScrollViewDelegate
{
public event EventHandler<bool> ProcessCompleted;
public override void Scrolled(UIScrollView scrollView)
{
if (scrollView.ContentOffset.Y >= scrollView.ContentSize.Height - scrollView.Frame.Size.Height)
{
System.Diagnostics.Debug.WriteLine("Bottom Reached");
ProcessCompleted?.Invoke(this,true);
}
else
{
ProcessCompleted?.Invoke(this,false);
}
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。