Ответ 1
В соответствии с этим отчет о выпуске, это невозможно. Если веб-код находится под вашим контролем, вы можете реализовать некоторый JavaScriptInterface для обхода этого. Если нет, я боюсь, что здесь нет решения.
Как я могу определить, использовал ли Android WebView событие касания? onTouchEvent
всегда возвращает true и WebViewClient
onUnhandledInputEvent
никогда не запускается.
У меня есть несколько WebView внутри TwoDScrollView. Как следует из названия, TwoDScrollView можно прокручивать как по вертикали, так и по горизонтали. Содержимое TwoDScrollView можно увеличить или уменьшить. Когда пользователь перетаскивает свой палец или использует щепотку для увеличения, я хочу отправить событие касания на:
Я частично добился этого, используя методы canScrollHorizontally
и canScrollVertically
. Но эти методы работают только для "родной прокрутки". Однако в некоторых случаях некоторый JavaScript внутри WebView потребляет сенсорное событие, например Google Maps. В этом случае методы возвращают false. Есть ли способ узнать, потребляет ли содержимое WebView события касания, то есть прокручивается/масштабируется? Я не могу изменить содержимое WebView, поэтому мой вопрос отличается от этого.
Я рассмотрел проверку обработчиков касаний, выполнив некоторый JavaScript внутри Webview с помощью метода evaluateJavaScript
, но в соответствии с этим ответом нет простого способа достичь этого а также страница может иметь некоторые другие вложенные фреймы. Любая помощь будет оценена.
onTouchEvent
и читал super.onTouchEvent()
, который всегда возвращает true, независимо от того, что.canScrollHorizontally
и canScrollVertically
только частично решают эту проблему, как указано выше.onScrollChanged
не полезенWebViewClient.onUnhandledInputEvent
никогда не запускаетсяevaluateJavaScript
, но это очень сложное и уродливое решениеDebug.startMethodTracing
. Я узнал, что он распространяется следующим образом:
android.webkit.WebView.onTouchEvent
com.android.webview.chromium.WebViewChromium.onTouchEvent
com.android.org.chromium.android_webview.AwContents.onTouchEvent
com.android.org.chromium.android_webview.AwContents$AwViewMethodsImpl.onTouchEvent
com.android.org.chromium.content.browser.ContentViewCore.onTouchEventImpl
nativeOnTouchEvent
, и я не знаю, что с ним происходит дальше, Во всяком случае, onTouchEvent
всегда возвращает true, и даже если бы можно было узнать где-то, было ли это событие поглощено или нет, для этого потребуется использование частных методов, которые также довольно уродливы.Мне не нужно знать, как перехватывать события касания, отправляемые в WebView, но использует ли их WebView, т.е. использует их для чего-либо, например, прокрутки, перетаскивания и т.д.
В соответствии с этим отчет о выпуске, это невозможно. Если веб-код находится под вашим контролем, вы можете реализовать некоторый JavaScriptInterface для обхода этого. Если нет, я боюсь, что здесь нет решения.
Вы можете передать все события touch
в GestureDetector
, переопределив onTouchEvent
из WebView
, чтобы вы могли знать , когда Android WebView потребляет события касания в любом месте и в любое время, слушая GestureDetector
.
Попробуйте вот так:
public class MyWebView extends WebView {
private Context context;
private GestureDetector gestDetector;
public MyWebView(Context context) {
super(context);
this.context = context;
gestDetector = new GestureDetector(context, gestListener);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return gd.onTouchEvent(event);
}
GestureDetector.SimpleOnGestureListener gestListener= new GestureDetector.SimpleOnGestureListener() {
public boolean onDown(MotionEvent event) {
return true;
}
public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {
//if (event1.getRawX() > event2.getRawX()) {
// show_toast("swipe left");
//} else {
// show_toast("swipe right");
//}
//you can trace any touch events here
return true;
}
};
void show_toast(final String text) {
Toast t = Toast.makeText(context, text, Toast.LENGTH_SHORT);
t.show();
}
}
Надеюсь, ты вдохновлен.
Этот код будет обрабатывать ваши прокрутки событий в веб-просмотре. Это улавливает клик и события нажатия, и сравнивает позиции каждого из них. Он не имеет в виду, что контент в веб-просмотре прокручивается, просто сравните координаты в области веб-просмотра.
public class MainActivity extends Activity implements View.OnTouchListener, Handler.Callback {
private float x1,x2,y1,y2; //x1, y1 is the start of the event, x2, y2 is the end.
static final int MIN_DISTANCE = 150; //min distance for a scroll event
private static final int CLICK_ON_WEBVIEW = 1;
private static final int CLICK_ON_URL = 2;
private static final int UP_ON_WEBVIEW = 3;
private final Handler handler = new Handler(this);
public WebView webView;
private WebViewClient client;
private WebAppInterface webAppInt = new WebAppInterface(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView)findViewById(R.id.myWebView);
webView.setOnTouchListener(this);
client = new WebViewClient();
webView.setWebViewClient(client);
webView.loadDataWithBaseURL("file:///android_asset/", "myweb.html", "text/html", "UTF-8", "");
}
//HERE START THE IMPORTANT PART
@Override
public boolean onTouch(View v, MotionEvent event) {
if (v.getId() == R.id.myWebView && event.getAction() == MotionEvent.ACTION_DOWN){
x1 = event.getX();
y1 = event.getY();
handler.sendEmptyMessageDelayed(CLICK_ON_WEBVIEW, 200);
} else if (v.getId() == R.id.myWebView && event.getAction() == MotionEvent.ACTION_UP){
x2 = event.getX();
y2 = event.getY();
handler.sendEmptyMessageDelayed(UP_ON_WEBVIEW, 200);
}
return false;
}
@Override
public boolean handleMessage(Message msg) {
if (msg.what == CLICK_ON_URL){ //if you clic a link in the webview, thats not a scroll
handler.removeMessages(CLICK_ON_WEBVIEW);
handler.removeMessages(UP_ON_WEBVIEW);
return true;
}
if (msg.what == CLICK_ON_WEBVIEW){
//Handle the click in the webview
Toast.makeText(this, "WebView clicked", Toast.LENGTH_SHORT).show();
return true;
}
if (msg.what == UP_ON_WEBVIEW){
float deltaX = x2 - x1; //horizontal move distance
float deltaY = y2 - y1; //vertical move distance
if ((Math.abs(deltaX) > MIN_DISTANCE) && (Math.abs(deltaX) > Math.abs(deltaY)))
{
// Left to Right swipe action
if (x2 > x1)
{
//Handle the left to right swipe
Toast.makeText(this, "Left to Right swipe", Toast.LENGTH_SHORT).show ();
}
// Right to left swipe action
else
{
//Handle the right to left swipe
Toast.makeText(this, "Right to Left swipe", Toast.LENGTH_SHORT).show ();
}
}
else if ((Math.abs(deltaY) > MIN_DISTANCE) && (Math.abs(deltaY) > Math.abs(deltaX)))
{
// Top to Bottom swipe action
if (y2 > y1)
{
//Handle the top to bottom swipe
Toast.makeText(this, "Top to Bottom swipe", Toast.LENGTH_SHORT).show ();
}
// Bottom to top swipe action -- I HIDE MY ACTIONBAR ON SCROLLUP
else
{
getActionBar().hide();
Toast.makeText(this, "Bottom to Top swipe [Hide Bar]", Toast.LENGTH_SHORT).show ();
}
}
return true;
}
return false;
}
}
Вы также можете попытаться контролировать скорость салфетки, чтобы обнаружить ее как реальную прокрутку или прокрутку.
Я надеюсь, что это поможет вам.
Попробуйте установить android:isClickable="true"
в XML и создать onClickListener
в коде Java.