ProgramingTip

Android WebView가 터치 이벤트를 소비하는지 확인

bestdevel 2020. 12. 9. 21:30
반응형

Android WebView가 터치 이벤트를 소비하는지 확인


짧은 버전

Android WebView가 터치 이벤트를 사용하여 어떻게 감지 할 수 있습니까? onTouchEvent항상 진정한를 반환하고 WebViewClientonUnhandledInputEvent는 트리거되지 않습니다.

상세 버전

TwoDScrollView에는 여러 WebView가 있습니다. TwoDScrollView는 수직 및 수평으로 스크롤 할 수 있습니다. TwoDScrollView의 내용을 확대 / 축소 할 수 있습니다. 사용자가 손가락을 끌거나 핀치 투 줌을 사용할 때 터치 이벤트를 다음으로 전달하고 싶습니다.

  • 콘텐츠가 스크롤 / 확대 / 축소 가능한 경우 WebView (예 : WebView 내부 만 스크롤 / 확대 / 축소)
  • 위의 조건이 false 인 경우 TwoDScrollView (TwoDScrollView의 모든 내용이 스크롤 / 줌)

나는 canScrollHorizontallycanScrollVertically방법 을 사용하여 부분적으로 달성했다 . 그러나 유일한 방법은 "기본 스크롤"에서만 작동합니다. 그러나 경우에 따라 WebView 내의 일부 JavaScript가 터치 이벤트를 사용합니다 (예 : Google Maps). 이 경우 메서드는 거짓을 반환합니다. WebView의 콘텐츠가 터치 이벤트를 사용하는지 여부를 확인할 수있는 방법이 있습니까? 질문은 다른 내 따라서 웹보기의 내용을 변경할 수 없습니다 이것 .

evaluateJavaScript메서드로 웹보기 내에서 일부 자바 스크립트를 실행하여 터치를 핸들러를 확인하는 것을 고려 했지만 이 답변 에 따르면 를 달성하는 쉬운 방법이 없으며 페이지에 다른 중첩 된 iframe 대응이있을 수 있습니다. 어떤 도움을 주시면 감사하겠습니다.

내가 이미 시도한 것

  1. 나는 WebView를 무시 onTouchEvent하고 super.onTouchEvent()무엇이든지 항상 참을 반환하는 것을 읽었습니다 .
  2. canScrollHorizontally그리고 canScrollVertically전술 한 바와 같이 부분적으로 만,이 문제를
  3. onScrollChanged 유용하지도 않다
  4. WebViewClient.onUnhandledInputEvent 트리거되지 않음
  5. 를 통해 JavaScript 사용을 고려 evaluateJavaScript했지만 복잡하고 추악한 솔루션입니다.
  6. MotionEvent를 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
    • ContentViewCore의 소스 코드 에 따르면 터치 이벤트는 방법으로 끝나고 nativeOnTouchEvent더 이상 어떤 일이 발생하는지습니다. 어쨌든, onTouchEvent항상 true를 반환하고 이벤트가 소비하는지 여부를 어딘가에서 사용하더라도 매우 추한 방법을 사용합니다.

노트

WebView로 된 터치 이벤트를 가로채는 방법을 알 필요는 없지만 WebView 가이를 소비하는지, 즉 스크롤, 끌어 전송 같은 작업에 사용하는지 여부.


문제 보고서 에 따르면 불가능합니다. 코드를 제어 할 수있는 경우 일부 JavaScript 인터페이스를 구현하여 웹에서 문제를 해결할 수 있습니다. 그것은 않다면 여기에 해결되지 않습니다.


은 모든 전달할 당신 수있는 touch이벤트를 GestureDetector재정 의하여 onTouchEventWebView당신이 알 수 있도록, 안드로이드 웹보기는 언제 어디서나 터치 이벤트를 소비 할 때 듣고에 의해 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();
    }
}

영감을 바랍니다시기 바랍니다.


이 코드는 웹뷰에서 스크롤링 이벤트를 처리합니다. 클릭 다운 및 클릭 업 이벤트를 발생하고 각 이벤트의 위치를 ​​비교합니다. webview 내 콘텐츠가 전개 될 것이라고 생각하는 신경 쓰지 않고 webview 영역의 좌표를 비교하기 만하면됩니다.

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 코드에서 작성 합니다.

참고 URL : https://stackoverflow.com/questions/29821565/check-if-android-webview-is-sumption-touch-events

반응형