Отключить прокрутку в webview?
до сих пор я был только разработчиком iPhone, и теперь я решил дать Android вихрь. То, что я не смог выяснить на Android, - это как программно предотвратить прокрутку в WebView
?
что-то похожее на предотвращение iPhones onTouchMove
событие было бы здорово!
15 ответов
вот мой код отключение всех прокрутки в 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 с вертикальной прокруткой scrollview и отключить все прокрутка в 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>
и set
webview.setScrollContainer(false);
не забудьте добавить webview.setOnTouchListener(...)
код выше, чтобы отключить всю прокрутку в webview. Вертикальный ScrollView позволит прокручивать содержимое WebView.
Я не знаю, нужно ли вам это или нет, но вот решение:
appView = (WebView) findViewById(R.id.appView);
appView.setVerticalScrollBarEnabled(false);
appView.setHorizontalScrollBarEnabled(false);
делает 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
звонки doDrag
которых звонки overScrollBy.
добавление сведений о полях в тело предотвратит прокрутку, если ваш контент правильно обертывается, например:
<body leftmargin="0" topmargin="0" rightmargin="0" bottommargin="0">
достаточно легко, и намного меньше кода + ошибка накладные расходы:)
установите прослушиватель в вашем WebView:
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);
}
мое грязное, но простое в реализации и хорошо работающее решение:
просто поместите webview внутри scrollview. Сделайте webview слишком большим, чем возможный контент (в одном или обоих измерениях, в зависимости от требований). ..и настройте полосы прокрутки scrollview, как вы хотите.
пример отключения горизонтальной полосы прокрутки в 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>
надеюсь, это поможет;)
для Disbale прокрутки используйте это
объект WebView.setOnTouchListener(новый вид.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
return (event.getAction() == MotionEvent.ACTION_MOVE);
}
});
это не может быть источником вашей проблемы, но я потратил часы, пытаясь отследить, почему мое приложение, которое отлично работало на iphone, заставляет браузер android постоянно подбрасывать вертикальные / горизонтальные полосы прокрутки и фактически перемещать страницу. У меня был тег тела html с высотой и шириной, установленной на 100%, и тело было полно различных тегов в разных местах. Независимо от того, что я пытался, браузеры android будут показывать свои полосы прокрутки и перемещать страницу немного, особенно при выполнении быстрого свайпа. Решение, что работал для меня без необходимости делать что-либо в APK-файл чтобы добавить в тег body:
leftmargin="0" topmargin="0"
похоже, что поля по умолчанию для тега body применялись к дроиду, но игнорировались на iphone
Если вы подкласс 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);
}
...
я разрешил мерцание и автоматическую прокрутку:
webView.setFocusable(false);
webView.setFocusableInTouchMode(false);
однако, если он по-прежнему не работает по какой-то причине, просто сделайте класс, который расширяет WebView, и поместите на него этот метод:
// disable scroll on touch
setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return (event.getAction() == MotionEvent.ACTION_MOVE);
}
});
Я предлагаю расширить WebView, чтобы обеспечить более эффективный контроль, например, отключить / включить swipes, включить / отключить касания, прослушиватели, переходы управления, анимацию, определить настройки внутри и так далее..
изучение вышеуказанных ответов почти сработало для меня ... но у меня все еще была проблема, что я мог "бросить" вид на 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);
}
}
/ / отключить всю прокрутку
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
Это должен быть полный ответ. Как предложил @GDanger . Расширьте WebView, чтобы переопределить методы прокрутки и внедрить пользовательский webview в XML макета.
public class ScrollDisabledWebView extends WebView {
private boolean scrollEnabled = false;
public ScrollDisabledWebView(Context context) {
super(context);
initView(context);
}
public ScrollDisabledWebView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
initView(context);
}
// this is important. Otherwise it throws Binary Inflate Exception.
private void initView(Context context) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY,
int scrollRangeX, int scrollRangeY, int maxOverScrollX,
int maxOverScrollY, boolean isTouchEvent) {
if (scrollEnabled) {
return super.overScrollBy(deltaX, deltaY, scrollX, scrollY,
scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
}
return false;
}
@Override
public void scrollTo(int x, int y) {
if (scrollEnabled) {
super.scrollTo(x, y);
}
}
@Override
public void computeScroll() {
if (scrollEnabled) {
super.computeScroll();
}
}
}
а затем встроить в файл макета следующим образом
<com.sample.apps.ScrollDisabledWebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
tools:context="com.sample.apps.HomeActivity"/>
затем в действии используйте некоторые дополнительные методы для отключения полос прокрутки.
ScrollDisabledWebView webView = (ScrollDisabledWebView) findViewById(R.id.webView);
webView.setVerticalScrollBarEnabled(false);
webView.setHorizontalScrollBarEnabled(false);