如何以编程方式滚动 Android WebView
Posted
技术标签:
【中文标题】如何以编程方式滚动 Android WebView【英文标题】:How to Programmatically Scroll Android WebView 【发布时间】:2011-01-15 09:16:32 【问题描述】:我正在尝试以编程方式将 WebView 滚动到 DOM 树中特定元素的位置。但到目前为止,我还无法让 WebView 响应滚动请求。我尝试调用使用 window.scrollTo(...)
的 javascript,但 WebView 没有响应。在 Java 方面,我尝试调用 WebView.flingScroll(...)
方法。 WebView 将响应flingScroll
,但我需要的是scrollTo(...)
功能。有什么想法吗?
【问题讨论】:
【参考方案1】:我找到了一个更好的答案来解决这个问题。事实证明,WebView
确实具有您所期望的 scrollTo()
、getScrollX()
和 getScrollY()
方法。它们在文档中有点隐藏,因为它们继承自 View
(通过 AbsoluteLayout
-> ViewGroup
-> View
)。这显然是比有些繁琐的 JavaScript 界面更好的方式来操纵WebView
的滚动位置。
【讨论】:
很高兴你回来添加这个:) 这是一个很好的解决方案。但我想做一些额外的事情。我有一个包含学校课程(带有一些标签)的 html 文件,以及一个包含该课程解释录音的音频文件。我想根据在后台播放的音频文件滚动我的 web 视图(包含 html 文件)。如果我转发音频文件,那么我的滚动条也会移动到当前播放音频的位置。你有什么建议吗? @Steve:它对我来说很好用,但我想在顶部滚动网页视图(即网页视图的开始位置)。我正在使用 mScrollView.scrollTo(0.mScrollView.getScrollY()) 但它不起作用。 @SteveLiddle:它适用于滚动视图,但不适用于 webView。我想将它应用于 webView。还有一个人认为我需要你的建议,我想在某个时间间隔内将网页视图自动滚动到特定位置。我为此使用 findAll("tag") 和 findNext(true) 。它工作正常,但它滚动到屏幕底部的“标签”,我想滚动它直到屏幕顶部的“标签”。谢谢。 @Maarten,一个元素可以报告它的位置,你可以通过编写一些 JavaScript 来获得它。我认为你想对 DOM 树做的任何事情都需要在 JavaScript 中进行,而不是在 Objective-C 中。【参考方案2】:事实证明window.scrollTo()
确实有效,您只是不能添加自己的名为scrollTo()
的方法。出于某种原因,当我调用window.scrollTo()
时,我自己的scrollTo()
方法被调用了。
因此,总而言之,要将 WebView 滚动到特定的 DOM 元素,请编写 JavaScript
函数来进行滚动:
function scrollToElement(id)
var elem = document.getElementById(id);
var x = 0;
var y = 0;
while (elem != null)
x += elem.offsetLeft;
y += elem.offsetTop;
elem = elem.offsetParent;
window.scrollTo(x, y);
然后从您的 android 应用程序(Java 代码)中,告诉您的 WebView 加载 URL:
webView.loadUrl("javascript:scrollToElement('" + elemId + "')");
这种方法存在一些问题,例如滚动的动画效果不佳,但一般机制有效。
DOM 窗口对象确实正确报告了 WebView 的当前滚动位置(参见window.pageXOffset
、window.pageYOffset
或window.scrollX
、window.scrollY)
。如果您只想知道 WebView 当前的滚动位置,请编写一些 JavaScript 来调用您的 Java 代码并传递 X/Y 偏移量。
【讨论】:
发生这种情况是因为在全局范围内声明函数时,它实际上被声明为全局window
对象的属性。【参考方案3】:
使用 Java 代码无法做到这一点。
对于所有被这个问题困扰的人,我有一些关于在 android 中滚动 webview 的结论。
您无法使用 Java 代码滚动 web 视图或获取滚动位置。 只能获取webview的layoutHeight、measuredHeight、contentHeight,仅此而已。这些都是允许您获取和设置滚动状态的 android api。 但是,您可以重写 onScorllChanged 为滚动 webview 事件(或 fling 事件)添加自定义侦听器,您将被通知原始位置和新位置。 好吧,您可以使用 JavaScript 代码滚动到某个位置,如下所示,但性能确实很差。如果您想经常滚动它,请三思而后行。window.scrollTo(100,500)
考虑您的情况并选择合适的解决方案。另请注意,fling 和 scroll 是不同的东西。
【讨论】:
【参考方案4】: @Override
public void onPageFinished(final WebView view, String url)
super.onPageFinished(view, url);
new Handler().postDelayed(new Runnable()
@Override
public void run()
if (app.scrollCache.containsKey(app.srctid))
app.scrollSpot=app.scrollCache.get(app.srctid);
view.scrollTo(0,(int)app.scrollSpot);
pageFinished=true;
, 200);
【讨论】:
【参考方案5】:以下单行解决方案可确保将所选元素带入视野(如果不是)。在某些情况下,这可能就足够了。
webView.loadUrl("javascript:document.getElementById('"+aID+"').scrollIntoView()");
【讨论】:
以上是关于如何以编程方式滚动 Android WebView的主要内容,如果未能解决你的问题,请参考以下文章
Android 可滚动的 AlertDialog 以编程方式