禁用在webview中滚动?
到目前为止,我只是一名iPhone开发人员,现在我决定给Android一个旋风。 我一直没能弄清楚的东西是如何以编程方式防止在WebView
滚动?
类似iPhone防止onTouchMove
事件将是伟大的!
这里是我禁用 webview中所有滚动的代码:
// disable scroll on touch webview.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return (event.getAction() == MotionEvent.ACTION_MOVE); } });
只隐藏滚动条,但不禁用滚动:
WebView.setVerticalScrollBarEnabled(false); WebView.setHorizontalScrollBarEnabled(false);
或者你可以尝试使用单列布局,但这只适用于简单的页面,并禁用水平滚动:
//Only disabled the horizontal scrolling: webview.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
您也可以尝试使用垂直滚动滚动视图来包装您的webview ,并禁用所有在webview上的滚动:
<ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent" android:scrollbars="vertical" > <WebView android:id="@+id/mywebview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scrollbars="none" /> </ScrollView>
并设置
webview.setScrollContainer(false);
不要忘记添加上面的webview.setOnTouchListener(…)代码来禁用所有在web视图中的滚动。 垂直的ScrollView将允许滚动WebView的内容。
我不知道你是否还需要它,但这里是解决scheme:
appView = (WebView) findViewById(R.id.appView); appView.setVerticalScrollBarEnabled(false); appView.setHorizontalScrollBarEnabled(false);
如果您的内容正确包装,则将边距细节添加到正文将防止滚动,如下所示:
<body leftmargin="0" topmargin="0" rightmargin="0" bottommargin="0">
很简单,less了很多代码+ bug的开销:)
使WebView
忽略运动事件是错误的方法去做。 如果WebView
需要了解这些事件怎么办?
相反,子类WebView
并重写非私有滚动方法。
public class NoScrollWebView extends WebView { ... @Override public boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { return false; } @Override public void scrollTo(int x, int y) { // Do nothing } @Override public void computeScroll() { // Do nothing } }
如果您查看WebView
的源代码 ,则可以看到onTouchEvent
调用了调用overScrollBy的doDrag 。
在你的webview上设置一个监听器:
// breakingart.com: This prevents the webview being scrolled webView.setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { return(event.getAction() == MotionEvent.ACTION_MOVE)); } });
我还没有尝试过,因为我还没有遇到这个问题,但也许你可以超越onScroll函数?
@Override public void scrollTo(int x, int y){ super.scrollTo(0,y); }
我的肮脏,但易于实施和良好的工作解决scheme:
简单地把webview里面的滚动视图。 使webview远远大于可能的内容(在一个或两个维度,取决于要求)。 ..并设置滚动视图的滚动条(S),如你所愿。
示例以禁用webview上的水平滚动条:
<ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent" android:scrollbars="vertical" > <WebView android:id="@+id/mywebview" android:layout_width="1000dip" android:layout_height="fill_parent" /> </ScrollView>
我希望这有帮助 ;)
滚动滚动使用这个
webView.setOnTouchListener(new View.OnTouchListener(){
public boolean onTouch(View v, MotionEvent event) { return (event.getAction() == MotionEvent.ACTION_MOVE); } });
这可能不是你的问题的来源,但我花了几个小时,试图追查为什么我的应用程序在iphone上运行良好,导致Android浏览器不断抛出垂直/水平滚动条,实际移动页面。 我有一个高度和宽度设置为100%的HTML身体标记,身体充满了不同位置的各种标签。 无论我尝试什么,android浏览器都会显示滚动条,并且只是稍微移动页面,特别是在快速滑动时。 对于我而言,无需在APK中执行任何操作的解决scheme就是将以下代码添加到body标签中:
leftmargin="0" topmargin="0"
似乎身体标记的默认边距被应用在机器人上,但在iphone上被忽略
研究上面的答案几乎对我有效……但我仍然有一个问题,我可以“扔”2.1的观点(似乎是固定的2.2和2.3)。
这是我的最终解决scheme
public class MyWebView extends WebView { private boolean bAllowScroll = true; @SuppressWarnings("unused") // it is used, just java is dumb private long downtime; public MyWebView(Context context, AttributeSet attrs) { super(context, attrs); } public void setAllowScroll(int allowScroll) { bAllowScroll = allowScroll!=0; if (!bAllowScroll) super.scrollTo(0,0); setHorizontalScrollBarEnabled(bAllowScroll); setVerticalScrollBarEnabled(bAllowScroll); } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: if (!bAllowScroll) downtime = ev.getEventTime(); break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: if (!bAllowScroll) { try { Field fmNumSamples = ev.getClass().getDeclaredField("mNumSamples"); fmNumSamples.setAccessible(true); Field fmTimeSamples = ev.getClass().getDeclaredField("mTimeSamples"); fmTimeSamples.setAccessible(true); long newTimeSamples[] = new long[fmNumSamples.getInt(ev)]; newTimeSamples[0] = ev.getEventTime()+250; fmTimeSamples.set(ev,newTimeSamples); } catch (Exception e) { e.printStackTrace(); } } break; } return super.onTouchEvent(ev); } @Override public void flingScroll(int vx, int vy) { if (bAllowScroll) super.flingScroll(vx,vy); } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { if (bAllowScroll) super.onScrollChanged(l, t, oldl, oldt); else if (l!=0 || t!=0) super.scrollTo(0,0); } @Override public void scrollTo(int x, int y) { if (bAllowScroll) super.scrollTo(x,y); } @Override public void scrollBy(int x, int y) { if (bAllowScroll) super.scrollBy(x,y); } }
如果您为Webview创build子类 ,则只需重写onTouchEvent即可过滤触发滚动的移动事件。
public class SubWebView extends WebView { @Override public boolean onTouchEvent (MotionEvent ev) { if(ev.getAction() == MotionEvent.ACTION_MOVE) { postInvalidate(); return true; } return super.onTouchEvent(ev); } ...
我解决了闪烁和自动滚动:
webView.setFocusable(false); webView.setFocusableInTouchMode(false);
//禁用所有滚动
WebView.setVerticalScrollBarEnabled(false); WebView.setHorizontalScrollBarEnabled(false); webview.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return (event.getAction() == MotionEvent.ACTION_MOVE); } });
//仅禁用水平滚动
WebView.setHorizontalScrollBarEnabled(false); webview.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
//仅禁用垂直滚动
WebView.setVerticalScrollBarEnabled(false); webview.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (action) { case (MotionEvent.ACTION_DOWN): /** * get Y position */ start_y = event.getY(); break; case (MotionEvent.ACTION_MOVE): /*Disable vertical scrolling*/ if (start_y-event.getY()>THRESHOLD_VALUE || start_y- event.getY()<-THRESHOLD_VALUE) return true; break; } } });
在我的情况下,阈值是20
使用下面提到的类来禁用web视图中的水平滚动。
public class CustomWebView extends WebView implements View.OnTouchListener { // the initial touch points x coordinate private float touchDownX; private OnScrollChangedCallback mOnScrollChangedCallback; public CustomWebView(final Context context) { super(context); // make vertically scrollable only makeVerticalScrollOnly(); } public CustomWebView(final Context context, final AttributeSet attrs) { super(context, attrs); // make vertically scrollable only makeVerticalScrollOnly(); } public CustomWebView(final Context context, final AttributeSet attrs, final int defStyle) { super(context, attrs, defStyle); // make vertically scrollable only makeVerticalScrollOnly(); } @Override protected void onScrollChanged(final int l, final int t, final int oldl, final int oldt) { super.onScrollChanged(l, t, oldl, oldt); if (mOnScrollChangedCallback != null) mOnScrollChangedCallback.onScroll(l, t); } public OnScrollChangedCallback getOnScrollChangedCallback() { return mOnScrollChangedCallback; } public void setOnScrollChangedCallback(final OnScrollChangedCallback onScrollChangedCallback) { mOnScrollChangedCallback = onScrollChangedCallback; } /** * Impliment in the activity/fragment/view that you want to listen to the webview */ public static interface OnScrollChangedCallback { public void onScroll(int l, int t); } /** * make this {@link WebView} vertically scroll only */ private void makeVerticalScrollOnly() { // set onTouchListener for vertical scroll only setOnTouchListener(this); // hide horizontal scroll bar setHorizontalScrollBarEnabled(false); } @Override public boolean onTouch(View view, MotionEvent motionEvent) { // multitouch is ignored if (motionEvent.getPointerCount() > 1) { return true; } // handle x coordinate on single touch events switch (motionEvent.getAction()) { // save the x coordinate on touch down case MotionEvent.ACTION_DOWN: touchDownX = motionEvent.getX(); break; // reset the x coordinate on each other touch action, so it doesn't move case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: motionEvent.setLocation(touchDownX, motionEvent.getY()); break; } // let the super view handle the update return false; } }
只需在您的webView上使用android:focusableInTouchMode="false"
。