До цього часу я був лише розробником iPhone, а тепер вирішив закрутити Android. Щось, що я не зміг зрозуміти на Android, це як програмно запобігти прокрутці в WebView
?
Щось схоже на запобігання onTouchMove
заходу iPhones було б чудово!
До цього часу я був лише розробником iPhone, а тепер вирішив закрутити Android. Щось, що я не зміг зрозуміти на Android, це як програмно запобігти прокрутці в WebView
?
Щось схоже на запобігання onTouchMove
заходу iPhones було б чудово!
Відповіді:
Ось мій код для відключення всієї прокрутки у веб-перегляді:
// 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.
MotionEvent.ACTION_MOVE
події, WebView
перегляньте мою відповідь нижче.
ACTION_MOVE
на setOnTouchListener
подія має деякі побічні ефекти , так що я б не рекомендував цей відповідь; 1. Швидкі пальці вважаються onclick
подіями на сторінці. 2. Запобігає переповненню прокрутки елементів на сторінці, це може знадобитися для належної взаємодії залежно від сайту. 3. touchmove
Подія JS . @GDanger має правильну відповідь, яка має перевагу над overScrollBy
розширенням, WebView
оскільки вона не має інших побічних ефектів, а лише запобігає прокрутці сторінки. stackoverflow.com/a/26129301/1244574
Я не знаю, потрібно це вам все ще чи ні, але ось рішення:
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));
}
});
return
рядка там є додаткова дужка . Крім того, це порушує події на полотні HTML5 та JavaScript.
event.getAction() != MotionEvent.ACTION_MOVE
, а такожreturn true
return false
ні return true
.
Я ще не пробував цього, оскільки ще не стикався з цією проблемою, але, можливо, ви могли б замінити функцію onScroll?
@Override
public void scrollTo(int x, int y){
super.scrollTo(0,y);
}
Моє брудне, але просте у реалізації та добре працює рішення:
Просто розмістіть веб-перегляд всередині прокрутки. Зробіть веб-перегляд занадто великим, ніж можливий вміст (в одному або обох вимірах, залежно від вимог). ..і налаштуйте смуги прокрутки прокрутки як завгодно.
Приклад вимкнення горизонтальної смуги прокрутки у веб-перегляді:
<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.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, щоб забезпечити більш ефективний контроль, наприклад, відключити / увімкнути салфетки, увімкнути / вимкнути дотики, слухачі, керувати переходами, анімацією, визначити параметри внутрішньо, тощо.
Щоб вимкнути прокрутку, скористайтеся цим
webView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event)
{
return (event.getAction() == MotionEvent.ACTION_MOVE);
}
});
Можливо, це не джерело вашої проблеми, але я годинами намагався відстежити, чому моя програма, яка чудово працювала на iphone, змушує браузер Android постійно викидати вертикальні / горизонтальні смуги прокрутки і фактично переміщати сторінку. У мене був HTML-тег body із висотою та шириною, встановленим на 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);
}
...
вивчення вищезазначених відповідей майже спрацювало для мене ... але у мене все ще була проблема, що я міг "перекинути" погляд на 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);
}
}
Це має бути повною відповіддю. Як запропонував @GDanger. Розширте 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);