如何判断WebView是否完全缩小

发布于 2024-10-10 13:06:27 字数 84 浏览 5 评论 0原文

我正在寻找一种方法来检测 WebView 是否完全缩小。我知道您可以从 ZoomOut() 获得布尔返回值,但这将执行缩小。我只是想简单地知道它是否可以。

I'm looking for a way to detect whether or not a WebView is zoomed out fully. I know you can get a boolean return value from ZoomOut(), but that will perform the zoom out. I just want to simply know whether or not it can.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

花开半夏魅人心 2024-10-17 13:06:27

我使用我的自定义 WebView 类。

获取WebView的视图高度和内部html网页的contentHeight

计算 defaultScale = WebView.getHeight() / WebView.getContentHeight();currentScale = WebView.getScale()

如果 defaultScale < currentScale 它已缩放。

public class NoZoomControllWebView extends WebView {

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @SuppressWarnings("deprecation")
    public boolean isZoomed () {
        boolean result = false;

        int contentHeight = getContentHeight();
        int viewHeight = getHeight();

        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN_MR1 ) {
            float scale = getScale();
            int temp = (int)(((float)viewHeight / (float)contentHeight) * 100);

            if (temp < (int)(scale * 100)) {
                result = true;
            }
        } else {
            float scale = getScale();
            int temp = (int)(((float)viewHeight / (float)contentHeight) * 100);

            if (temp < (int)(scale * 100)) {
                result = true;
            }
        }

        return result;
    }
}

I use my custom WebView class.

Get WebView's view height and inner html web page's contentHeight.

Calculate defaultScale = WebView.getHeight() / WebView.getContentHeight(); and currentScale = WebView.getScale().

If defaultScale < currentScale it's zoomed.

public class NoZoomControllWebView extends WebView {

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @SuppressWarnings("deprecation")
    public boolean isZoomed () {
        boolean result = false;

        int contentHeight = getContentHeight();
        int viewHeight = getHeight();

        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN_MR1 ) {
            float scale = getScale();
            int temp = (int)(((float)viewHeight / (float)contentHeight) * 100);

            if (temp < (int)(scale * 100)) {
                result = true;
            }
        } else {
            float scale = getScale();
            int temp = (int)(((float)viewHeight / (float)contentHeight) * 100);

            if (temp < (int)(scale * 100)) {
                result = true;
            }
        }

        return result;
    }
}
百思不得你姐 2024-10-17 13:06:27

getScaled()
已弃用,您应该使用 onScaleChanged
在您的 WebViewClient 上

您可以像这样使用它:

            private boolean zoomed = false, firstRun = true;

            @Override
            public void onScaleChanged(WebView view, float oldScale,
                    float newScale) {
                if (firstRun) {
                    initScale = newScale;
                    firstRun=false;
                    zoomed = false;
                }
                else {
                    if (newScale>oldScale) {
                        zoomed = true;
                    }
                    else {
                        if (newScale<initScale) {
                            zoomed = false;
                        }
                    }
                }
                super.onScaleChanged(view, oldScale, newScale);
            }

如果我们假设 WebView 从一开始就最大程度地缩小。

getScaled()
is deprecated you should use onScaleChanged
on your WebViewClient instead

You can use it like this:

            private boolean zoomed = false, firstRun = true;

            @Override
            public void onScaleChanged(WebView view, float oldScale,
                    float newScale) {
                if (firstRun) {
                    initScale = newScale;
                    firstRun=false;
                    zoomed = false;
                }
                else {
                    if (newScale>oldScale) {
                        zoomed = true;
                    }
                    else {
                        if (newScale<initScale) {
                            zoomed = false;
                        }
                    }
                }
                super.onScaleChanged(view, oldScale, newScale);
            }

if we presume the WebView is zoomed max out from the start.

暗藏城府 2024-10-17 13:06:27

创建您自己的类来扩展 WebView 并重写 ZoomOut() 方法。每次用户缩小时,调用 super.zoomOut()。将返回到具有类作用域的布尔变量的内容保存起来,以便可以使用 onSaveInstanceState() 或 SharedPreferences(如果需要)将其保留。

public class MyWebView extends WebView {

    // WebViews are generally zoomed out all the way when first created so set defaults
    private boolean lastZoomInResult = true;
    private boolean lastZoomOutResult = false;

    @Override
    public boolean zoomIn() {
        lastZoomInResult = super.zoomIn();
        return lastZoomInResult;
    }

    @Override
    public boolean zoomOut() {
        lastZoomOutResult = super.zoomOut();
        return lastZoomOutResult;
    }

编辑:针对这不适用于捏缩放...你是非常正确的,最终克里斯蒂安的答案是正确的。

我使用 DDMS 通过 USB 将手机连接到电脑。当我捏缩放 Webview 时,我看到以下内容...

01-06 03:18:19.052: DEBUG/SurfaceFlinger(92): Layer::setBuffers(this=0x849ac0), pid=23072, w=1, h=1
01-06 03:18:19.052: DEBUG/SurfaceFlinger(92): Layer::setBuffers(this=0x849ac0), pid=23072, w=1, h=1
01-06 03:18:19.082: DEBUG/SurfaceFlinger(92): Layer::requestBuffer(this=0x849ac0), index=0, pid=23072, w=480, h=74 success
01-06 03:18:19.832: DEBUG/SurfaceFlinger(92): Layer::setBuffers(this=0x738378), pid=23072, w=1, h=1
01-06 03:18:19.832: DEBUG/SurfaceFlinger(92): Layer::setBuffers(this=0x738378), pid=23072, w=1, h=1
01-06 03:18:19.852: DEBUG/SurfaceFlinger(92): Layer::requestBuffer(this=0x738378), index=0, pid=23072, w=480, h=74 success

简而言之,缩放的不是 WebView。实际上发生的是图形显示的数字缩放 - 无论放大或缩小,WebView 内容都保持完全相同的大小,但它会像数码相机上的数字缩放一样进行数字“放大”或“缩小”。

我不完全理解 SurfaceFlinger 是什么,但通过 Google 快速搜索,我们在这里谈论“设备驱动程序”的东西。

这些 SurfaceFlinger 日志消息中唯一发生变化的是“this=”的十六进制值,并且它们与缩放状态无关。上面记录了屏幕完全缩小时的两次捏合尝试。

Create your own class which extends WebView and override the zoomOut() method. Every time the user zooms out, call super.zoomOut(). Save what is returned to a boolean variable with class scope so it can be persisted with onSaveInstanceState() or in SharedPreferences if needed.

public class MyWebView extends WebView {

    // WebViews are generally zoomed out all the way when first created so set defaults
    private boolean lastZoomInResult = true;
    private boolean lastZoomOutResult = false;

    @Override
    public boolean zoomIn() {
        lastZoomInResult = super.zoomIn();
        return lastZoomInResult;
    }

    @Override
    public boolean zoomOut() {
        lastZoomOutResult = super.zoomOut();
        return lastZoomOutResult;
    }

EDIT: In response to this not working for pinch zoom... you are quite correct and ultimately Cristian's answer holds true.

I hooked my phone up via USB to my PC with DDMS. I see the following when I pinch zoom my Webview...

01-06 03:18:19.052: DEBUG/SurfaceFlinger(92): Layer::setBuffers(this=0x849ac0), pid=23072, w=1, h=1
01-06 03:18:19.052: DEBUG/SurfaceFlinger(92): Layer::setBuffers(this=0x849ac0), pid=23072, w=1, h=1
01-06 03:18:19.082: DEBUG/SurfaceFlinger(92): Layer::requestBuffer(this=0x849ac0), index=0, pid=23072, w=480, h=74 success
01-06 03:18:19.832: DEBUG/SurfaceFlinger(92): Layer::setBuffers(this=0x738378), pid=23072, w=1, h=1
01-06 03:18:19.832: DEBUG/SurfaceFlinger(92): Layer::setBuffers(this=0x738378), pid=23072, w=1, h=1
01-06 03:18:19.852: DEBUG/SurfaceFlinger(92): Layer::requestBuffer(this=0x738378), index=0, pid=23072, w=480, h=74 success

In short, it isn't WebView which is zooming. What's actually happening is a digital zoom of the graphics display - the WebView content stays exactly the same size regardless of a zoom in or out but it's being digitally 'magnified' or 'shrunk' like the digital zoom on a digital camera.

I don't fully understand what SurfaceFlinger is but from a quick Google search, we're talking 'device driver' stuff here.

The only thing that changes in those SurfaceFlinger log messages are the hex value for 'this=' and they bear no relevance to the zoom state. The above is logging two pinch attempts when the screen was fully zoomed out.

混浊又暗下来 2024-10-17 13:06:27

我很想知道其他人可能会想出什么,但我能够通过 javascript 实现这一点。这很令人沮丧,因为我可以在 WebView 的源代码中看到轻松确定这一点所需的值,但它们是私有的,没有吸气剂...

无论如何,我到目前为止的解决方案是添加一个 JavaScriptInterface,它允许我获取 document.body页面的.scrollWidth 值。这为我提供了可滚动宽度,尽管有 getContentHeight() 方法,但由于某种原因该宽度不可用。使用它,我可以计算它是否完全缩小。

下面是 javascript 接口调用的方法:

public void checkIfZoomedOut(int scrollWidth){
   int zoomedOutThreshold = 5; // If you want to include "nearly zoomed out"
   if( Math.abs(Math.ceil(mWebView.getScale() * scrollWidth) - mWebView.getWidth()) <= zoomedOutThreshold){
       // It is zoomed out
   } else {
       // It is zoomed in
   }

}

scrollWidth 是 document.body.scrollWidth

编辑: 经过进一步实验,我发现了名为computeHorizo​​ntalScrollRange() 和computeHorizo​​ntalScrollExtent() 的受保护方法,如果您将其子类化,则可以调用它们网页视图。您可以使用它们来确定水平滚动是否处于活动状态/是否需要。但是,某些网页可以完全缩小(WebView 不会让您进一步缩小)并且仍然具有水平滚动条,例如带有文本的网页。所以它并不完美。

I'm curious to see what else anyone might come up with but I was able to accomplish this through javascript. It's frustrating because I can see the values needed to easily determine this in the source code of the WebView but they are private with no getters...

Anyhow the solution I have so far is add a JavaScriptInterface which allows me to get the document.body.scrollWidth value for the page. This provides me with the scrollable width, which for some reason is not available even though there is a getContentHeight() method. Using this, I can calculate whether or not it is fully zoomed out.

Here is the method the javascript interface calls:

public void checkIfZoomedOut(int scrollWidth){
   int zoomedOutThreshold = 5; // If you want to include "nearly zoomed out"
   if( Math.abs(Math.ceil(mWebView.getScale() * scrollWidth) - mWebView.getWidth()) <= zoomedOutThreshold){
       // It is zoomed out
   } else {
       // It is zoomed in
   }

}

The scrollWidth is document.body.scrollWidth

Edit: After further experimenting I found protected methods called computeHorizontalScrollRange() and computeHorizontalScrollExtent() that can be called if you subclass the WebView. You can use them to determine if horizontal scrolling is active/needed. However, some webpages can be fully zoomed out (the WebView won't let you zoom out any further) and still have a horizontal scrollbar, such as webpages with text. So it's not perfect.

明天过后 2024-10-17 13:06:27
if( !webView.zoomOut () ){
   // couldn't zoom out because the zoom out did nothing :(
   // THIS IS WHAT YOU WANT TO KNOW!
} else{
    webView.zoomIn(); // restore
}

<块引用>

我只是想简单地知道它是否可以。

没有办法这样做。

if( !webView.zoomOut () ){
   // couldn't zoom out because the zoom out did nothing :(
   // THIS IS WHAT YOU WANT TO KNOW!
} else{
    webView.zoomIn(); // restore
}

I just want to simply know whether or not it can.

There's no way to do so.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文