Отключить прокрутку в веб-просмотре?
До сих пор я был разработчиком iPhone, и теперь я решил дать Android завихрение. Что-то, что мне не удалось выяснить на Android, - это программно предотвратить прокрутку в WebView
?
Нечто похожее на предотвращение iPhones события onTouchMove
было бы здорово!
Ответы
Ответ 1
Вот мой код для отключения всех прокрутки в веб-просмотре:
// 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);
Вы также можете попробовать обернуть свой веб-просмотр с помощью прокрутки с прокруткой по вертикали и отключить прокрутку на веб-просмотре:
<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(...) выше, чтобы отключить всю прокрутку в веб-просмотре. Вертикальный ScrollView позволит прокручивать содержимое WebView.
Ответ 2
Я не знаю, нужна ли вам эта проблема или нет, но вот решение:
appView = (WebView) findViewById(R.id.appView);
appView.setVerticalScrollBarEnabled(false);
appView.setHorizontalScrollBarEnabled(false);
Ответ 3
Выполнение 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
}
}
Если вы посмотрите source для WebView
, вы увидите, что onTouchEvent
вызывает doDrag
, который вызывает overScrollBy.
Ответ 4
Добавление деталей поля в тело предотвратит прокрутку, если ваш контент правильно обернут, так:
<body leftmargin="0" topmargin="0" rightmargin="0" bottommargin="0">
Достаточно легко и намного меньше накладных расходов на код +:)
Ответ 5
Установите прослушиватель на веб-просмотр:
// 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));
}
});
Ответ 6
Я не пробовал это, так как мне еще предстоит встретить эту проблему, но, возможно, вы могли бы перекрыть функцию onScroll?
@Override
public void scrollTo(int x, int y){
super.scrollTo(0,y);
}
Ответ 7
Мое грязное, но простое в использовании и хорошо работающее решение:
Просто разместите webview внутри scrollview. Сделайте веб-просмотр слишком большим, чем возможный контент (в одном или обоих измерениях, в зависимости от требований)...и настройте полосу прокрутки scrollview по своему желанию.
Пример отключения горизонтальной полосы прокрутки на веб-просмотре:
<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>
Я надеюсь, что это поможет;)
Ответ 8
Чтобы отобразить прокрутку, используйте
webView.setOnTouchListener(новый View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
return (event.getAction() == MotionEvent.ACTION_MOVE);
}
});
Ответ 9
Это не может быть источником вашей проблемы, но я потратил часы, пытаясь отследить, почему мое приложение, которое отлично работает на iphone, заставляет браузер android постоянно поднимать вертикальные/горизонтальные полосы прокрутки и фактически перемещать страницу. У меня был тег html body с высотой и шириной, установленный на 100%, и тело было полон различных тегов в разных местах. Независимо от того, что я пытался, браузеры Android отображали свои полосы прокрутки и немного перемещали страницу, особенно при быстром прокрутке. Решение, которое работало для меня без необходимости делать что-либо в APK, состояло в том, чтобы добавить в тег body следующее:
leftmargin="0" topmargin="0"
Кажется, что поля по умолчанию для тега тела применяются к дроиду, но игнорируются на iphone
Ответ 10
изучение приведенных ответов почти сработало для меня... но у меня все еще была проблема, что я мог бы "бросить" представление на 2.1 (казалось, исправлено с 2.2 и 2.3).
вот мое окончательное решение
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);
}
}
Ответ 11
Если вы подкласс Webview, вы можете просто переопределить 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);
}
...
Ответ 12
Я разрешил мерцание и автопрокрутку:
webView.setFocusable(false);
webView.setFocusableInTouchMode(false);
Ответ 13
//Отключить все прокрутки
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
Ответ 14
Используйте класс, указанный ниже, чтобы отключить горизонтальную прокрутку в веб-представлении.
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;
}
}
Ответ 15
Просто используйте android:focusableInTouchMode="false"
в своем веб-браузере.