在Android WebView中启用/禁用放大

Evg*_*acu 64 android zoom multi-touch android-webview

WebSettings中有一些与缩放相关的方法:

  • WebSettings.setSupportZoom
  • WebSettings.setBuiltInZoomControls

我发现他们在某些设备上的工作方式不同 例如,在我的Galaxy S上,默认情况下启用缩放功能,但在LG P500上它被禁用(现在我不知道如何启用仅捏缩放,但隐藏缩放按钮).

在P500上,当我打电话时,setBuiltInZoomControls(true)我得到这两个变体工作(多点触控和按钮).

如何在LG P500等设备上启用多点触控缩放和禁用缩放按钮?(另外,我知道HTC设备上存在同样的问题)

更新:这里几乎是解决方案的完整代码

if (ev.getAction() == MotionEvent.ACTION_DOWN ||
        ev.getAction() == MotionEvent.ACTION_POINTER_DOWN ||
        ev.getAction() == MotionEvent.ACTION_POINTER_1_DOWN ||
        ev.getAction() == MotionEvent.ACTION_POINTER_2_DOWN ||
        ev.getAction() == MotionEvent.ACTION_POINTER_3_DOWN) {
    if (multiTouchZoom && !buttonsZoom) {
        if (getPointerCount(ev) > 1) {
            getSettings().setBuiltInZoomControls(true);
            getSettings().setSupportZoom(true);
        } else {
            getSettings().setBuiltInZoomControls(false);
            getSettings().setSupportZoom(false);
        }
    }
}

if (!multiTouchZoom && buttonsZoom) {
    if (getPointerCount(ev) > 1) {
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码位于我onTouchEvent重写的WebView方法中.

yut*_*mmo 111

在API> = 11时,您可以使用:

wv.getSettings().setBuiltInZoomControls(true);
wv.getSettings().setDisplayZoomControls(false);
Run Code Online (Sandbox Code Playgroud)

根据SDK:

public void setDisplayZoomControls (boolean enabled) 
Run Code Online (Sandbox Code Playgroud)

自:API等级11

设置是否使用屏幕上的缩放按钮.启用内置缩放控件和禁用屏幕缩放控件的组合允许在没有屏幕控制的情况下进行缩放缩放

  • 太糟糕了60%以上的用户仍在使用pre-API 11 ...而且我在发布之后一年就说这个!发布建议时,数字是什么样的? (10认同)

gng*_*r44 37

我查看了源代码,WebView并得出结论,没有优雅的方法来完成你的要求.

我最终做的是子类化WebView和重写OnTouchEvent.在OnTouchEventfor中ACTION_DOWN,我检查有多少指针使用MotionEvent.getPointerCount().如果有多个指针,我打电话setSupportZoom(true),否则我打电话setSupportZoom(false).然后我打电话给super.OnTouchEvent().

这将在滚动时有效禁用缩放(从而禁用缩放控件),并在用户即将缩放时启用缩放.这不是一个好方法,但到目前为止它对我来说效果很好.

注意这getPointerCount()是在2.1中引入的,所以如果你支持1.6,你将不得不做一些额外的事情.

  • 我说我爱你了吗,gngr44? (10认同)

Luk*_*uth 29

我们在为客户开发Android应用程序时遇到了同样的问题,我设法"破解"了这个限制.

我查看了WebView类的Android源代码,并发现了一个与-object一起使用的updateZoomButtonsEnabled()方法,根据浏览器的当前比例启用和禁用缩放控件.ZoomButtonsController

我搜索了一个方法来返回ZoomButtonsController-instance并找到了getZoomButtonsController()-method,它返回了这个实例.

尽管声明了该方法public,但它没有在WebView-documentation中记录,Eclipse也找不到它.所以,我尝试了一些反思并创建了我自己的WebView-subclass来覆盖onTouchEvent()-method,它触发了控件.

public class NoZoomControllWebView extends WebView {

    private ZoomButtonsController zoom_controll = null;

    public NoZoomControllWebView(Context context) {
        super(context);
        disableControls();
    }

    public NoZoomControllWebView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        disableControls();
    }

    public NoZoomControllWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        disableControls();
    }

    /**
     * Disable the controls
     */
    private void disableControls(){
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
            // Use the API 11+ calls to disable the controls
            this.getSettings().setBuiltInZoomControls(true);
            this.getSettings().setDisplayZoomControls(false);
        } else {
            // Use the reflection magic to make it work on earlier APIs
            getControlls();
        }
    }

    /**
     * This is where the magic happens :D
     */
    private void getControlls() {
        try {
            Class webview = Class.forName("android.webkit.WebView");
            Method method = webview.getMethod("getZoomButtonsController");
            zoom_controll = (ZoomButtonsController) method.invoke(this, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        super.onTouchEvent(ev);
        if (zoom_controll != null){
            // Hide the controlls AFTER they where made visible by the default implementation.
            zoom_controll.setVisible(false);
        }
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

您可能希望删除不必要的构造函数,并可能对异常做出反应.

虽然这看起来很糟糕且不可靠,但它可以回到API Level 4(Android 1.6).


正如@jayellos在评论中指出的那样,getZoomButtonsController()Android 4.0.4及更高版本不再存在私有方法.

但是,它不需要.使用条件执行,我们可以检查我们是否在具有API Level 11+的设备上并使用公开的功能(请参阅@Yuttadhammo答案)来隐藏控件.

我更新了上面的示例代码来做到这一点.


Jac*_*alk 10

Ive modifiet Lukas Knuth的解决方案:

1)没有必要继承webview,

2)如果你没有在单独的类中放入不存在的方法,代码将在某些Android 1.6设备上的字节码验证期间崩溃

3)如果用户向上/向下滚动页面,仍会出现缩放控件.我只是将变焦控制器容器设置为可见性GONE

  wv.getSettings().setSupportZoom(true);
  wv.getSettings().setBuiltInZoomControls(true);
  if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
    // Use the API 11+ calls to disable the controls
    // Use a seperate class to obtain 1.6 compatibility
    new Runnable() {
      public void run() {
        wv.getSettings().setDisplayZoomControls(false);
      }
    }.run();
  } else {
    final ZoomButtonsController zoom_controll =
        (ZoomButtonsController) wv.getClass().getMethod("getZoomButtonsController").invoke(wv, null);
    zoom_controll.getContainer().setVisibility(View.GONE);
  }
Run Code Online (Sandbox Code Playgroud)


Mih*_*l M 7

Lukas Knuth有很好的解决方案,但在三星Galaxy SII的Android 4.0.4上,我仍然看起来变焦控制.我通过解决它

if (zoom_controll!=null && zoom_controll.getZoomControls()!=null)
{
   // Hide the controlls AFTER they where made visible by the default implementation.
   zoom_controll.getZoomControls().setVisibility(View.GONE);
}
Run Code Online (Sandbox Code Playgroud)

代替

if (zoom_controll != null){
   // Hide the controlls AFTER they where made visible by the default implementation.
   zoom_controll.setVisible(false);
}
Run Code Online (Sandbox Code Playgroud)