如何以编程方式滚动Android WebView

时间:2022-08-24 23:57:04

I'm trying to programmatically scroll a WebView to the location of a particular element in the DOM tree. But so far I haven't been able to get the WebView to respond to scroll requests. I've tried calling JavaScript that uses window.scrollTo(...), but the WebView doesn't respond. On the Java side, I've tried calling the WebView.flingScroll(...) method. WebView will respond to flingScroll, but what I need is a scrollTo(...) capability. Any ideas?

我正在尝试以编程方式将WebView滚动到DOM树中特定元素的位置。但到目前为止,我还没有能够让WebView响应滚动请求。我试过调用使用window.scrollTo(...)的JavaScript,但WebView没有响应。在Java方面,我尝试调用WebView.flingScroll(...)方法。 WebView将响应flingScroll,但我需要的是scrollTo(...)功能。有任何想法吗?

4 个解决方案

#1


46  

I've found a better answer to this issue. It turns out that WebView does have scrollTo(), getScrollX() and getScrollY() methods as you'd expect. They're a bit hidden in the documentation because they're inherited from View (via AbsoluteLayout -> ViewGroup -> View). This is obviously a better way to manipulate the WebView's scroll position than the somewhat cumbersome JavaScript interface.

我找到了一个更好的答案来解决这个问题。事实证明,WebView确实有你想要的scrollTo(),getScrollX()和getScrollY()方法。它们在文档中有点隐藏,因为它们是从View继承的(通过AbsoluteLayout - > ViewGroup - > View)。这显然是一种操作WebView滚动位置的更好方法,而不是有点麻烦的JavaScript界面​​。

#2


12  

It turns out that the window.scrollTo() DOES work, you just can't add your own method named scrollTo(). For some reason my own scrollTo() method was being invoked when I called window.scrollTo().

事实证明,window.scrollTo()DOES工作,你只是无法添加自己的名为scrollTo()的方法。出于某种原因,当我调用window.scrollTo()时,我调用了自己的scrollTo()方法。

So, in summary, to scroll a WebView to a particular DOM element, write a JavaScript function to do the scrolling:

因此,总而言之,要将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);
}

and then from your Android app (Java code), tell your WebView to load a URL:

然后从您的Android应用程序(Java代码),告诉您的WebView加载URL:

webView.loadUrl("javascript:scrollToElement('" + elemId + "')");

There are some issues with this approach, such as the scroll will not be nicely animated, but the general mechanism works.

这种方法存在一些问题,例如滚动不会很好地动画,但一般机制有效。

The DOM window object does report the current scroll position of the WebView correctly (see window.pageXOffset, window.pageYOffset or window.scrollX, window.scrollY). If you just want to know the current scroll position of the WebView, write some JavaScript to call your Java code and pass along the X/Y offsets.

DOM窗口对象会正确报告WebView的当前滚动位置(请参阅window.pageXOffset,window.pageYOffset或window.scrollX,window.scrollY)。如果您只想知道WebView的当前滚动位置,请编写一些JavaScript来调用Java代码并传递X / Y偏移量。

#3


0  

You cannot do that using Java Code.

你不能使用Java Code做到这一点。

For alls who are stuck at this problem, I have some conclusion about scrolling a webview in android.

对于那些坚持这个问题的人,我有一些关于在an​​droid中滚动webview的结论。

  • You cannot scroll a webview or get scrolling position using Java Code.
  • 您无法使用Java代码滚动Web视图或获取滚动位置。

  • You can only get layoutHeight, measuredHeight, contentHeight of a webview, nothing more. These are all the android api allowing you do in getting and setting scroll status.
  • 您只能获得webview的layoutHeight,measuredHeight,contentHeight,仅此而已。这些都是android api,允许你在获取和设置滚动状态。

  • But, you can override the onScorllChanged to add a self-define listener for scrolling webview event(or fling event), you will be notified the origin position and the new position.
  • 但是,您可以覆盖onScorllChanged以添加用于滚动webview事件(或fling事件)的自定义侦听器,您将被通知原点位置和新位置。

  • Well, you can scroll to a position using JavaScript code, like the following, but the performance is really poor. If you want to scroll it frequently, please give it a second thought.

    window.scrollTo(100,500)

  • 好吧,您可以使用JavaScript代码滚动到某个位置,如下所示,但性能非常差。如果你想经常滚动它,请再想一想。 window.scrollTo(100,500)

Consider your situation and choose a proper solution. Also be noticed that fling and scroll are different things.

考虑您的情况并选择合适的解决方案。还要注意的是,fling和scroll是不同的东西。

#4


0  

    @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);


    }

#1


46  

I've found a better answer to this issue. It turns out that WebView does have scrollTo(), getScrollX() and getScrollY() methods as you'd expect. They're a bit hidden in the documentation because they're inherited from View (via AbsoluteLayout -> ViewGroup -> View). This is obviously a better way to manipulate the WebView's scroll position than the somewhat cumbersome JavaScript interface.

我找到了一个更好的答案来解决这个问题。事实证明,WebView确实有你想要的scrollTo(),getScrollX()和getScrollY()方法。它们在文档中有点隐藏,因为它们是从View继承的(通过AbsoluteLayout - > ViewGroup - > View)。这显然是一种操作WebView滚动位置的更好方法,而不是有点麻烦的JavaScript界面​​。

#2


12  

It turns out that the window.scrollTo() DOES work, you just can't add your own method named scrollTo(). For some reason my own scrollTo() method was being invoked when I called window.scrollTo().

事实证明,window.scrollTo()DOES工作,你只是无法添加自己的名为scrollTo()的方法。出于某种原因,当我调用window.scrollTo()时,我调用了自己的scrollTo()方法。

So, in summary, to scroll a WebView to a particular DOM element, write a JavaScript function to do the scrolling:

因此,总而言之,要将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);
}

and then from your Android app (Java code), tell your WebView to load a URL:

然后从您的Android应用程序(Java代码),告诉您的WebView加载URL:

webView.loadUrl("javascript:scrollToElement('" + elemId + "')");

There are some issues with this approach, such as the scroll will not be nicely animated, but the general mechanism works.

这种方法存在一些问题,例如滚动不会很好地动画,但一般机制有效。

The DOM window object does report the current scroll position of the WebView correctly (see window.pageXOffset, window.pageYOffset or window.scrollX, window.scrollY). If you just want to know the current scroll position of the WebView, write some JavaScript to call your Java code and pass along the X/Y offsets.

DOM窗口对象会正确报告WebView的当前滚动位置(请参阅window.pageXOffset,window.pageYOffset或window.scrollX,window.scrollY)。如果您只想知道WebView的当前滚动位置,请编写一些JavaScript来调用Java代码并传递X / Y偏移量。

#3


0  

You cannot do that using Java Code.

你不能使用Java Code做到这一点。

For alls who are stuck at this problem, I have some conclusion about scrolling a webview in android.

对于那些坚持这个问题的人,我有一些关于在an​​droid中滚动webview的结论。

  • You cannot scroll a webview or get scrolling position using Java Code.
  • 您无法使用Java代码滚动Web视图或获取滚动位置。

  • You can only get layoutHeight, measuredHeight, contentHeight of a webview, nothing more. These are all the android api allowing you do in getting and setting scroll status.
  • 您只能获得webview的layoutHeight,measuredHeight,contentHeight,仅此而已。这些都是android api,允许你在获取和设置滚动状态。

  • But, you can override the onScorllChanged to add a self-define listener for scrolling webview event(or fling event), you will be notified the origin position and the new position.
  • 但是,您可以覆盖onScorllChanged以添加用于滚动webview事件(或fling事件)的自定义侦听器,您将被通知原点位置和新位置。

  • Well, you can scroll to a position using JavaScript code, like the following, but the performance is really poor. If you want to scroll it frequently, please give it a second thought.

    window.scrollTo(100,500)

  • 好吧,您可以使用JavaScript代码滚动到某个位置,如下所示,但性能非常差。如果你想经常滚动它,请再想一想。 window.scrollTo(100,500)

Consider your situation and choose a proper solution. Also be noticed that fling and scroll are different things.

考虑您的情况并选择合适的解决方案。还要注意的是,fling和scroll是不同的东西。

#4


0  

    @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);


    }