Android ScrollView крадет сенсорные события из дочернего WebView - PullRequest
0 голосов
/ 17 января 2019

У меня есть макет, где WebView находится внутри ScrollView, и я хочу иметь возможность переключаться между этими двумя, чтобы решить, какой из них получает сенсорные события. К сожалению, независимо от того, что я делаю, ScrollView, кажется, крадет сенсорные события из WebView, делая невозможным плавное панорамирование и масштабирование в WebView. Есть ли какое-то решение для этого?

Я попытался ScrollView.SetOnTouchListener(); и установил прослушиватель, который возвращает true, это останавливает прокрутку ScrollView, но не предотвращает перехват сенсорных событий до того, как они достигнут WebView.

Я также пробовал WebView.Parent.RequestDisallowInterceptTouchEvent(true); и WebView.Parent.RequestDisallowInterceptTouchEvent(true);, которые, похоже, не имеют никакого эффекта.

Ответы [ 2 ]

0 голосов
/ 20 января 2019

Я решил эту проблему, добавив плавающий WebView поверх экрана на том же уровне иерархии, что и ScrollView, и связал его положение со значением прокрутки, затем переключил сенсорное управление с помощью WebView.BringToFront и ScrollView.BringToFront

0 голосов
/ 17 января 2019

Попробуйте использовать NestedScrollView и внедрите NestedScrollingChild в пользовательский WebView.

Ссылка Ссылка

и некоторый код

public class NestedWebView extends WebView implements NestedScrollingChild {
private int mLastY;
private final int[] mScrollOffset = new int[2];
private final int[] mScrollConsumed = new int[2];
private int mNestedOffsetY;
private NestedScrollingChildHelper mChildHelper;

public NestedWebView(Context context) {
    this(context, null);
}

public NestedWebView(Context context, AttributeSet attrs) {
    this(context, attrs, android.R.attr.webViewStyle);
}

public NestedWebView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    mChildHelper = new NestedScrollingChildHelper(this);
    setNestedScrollingEnabled(true);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    boolean returnValue = false;

    MotionEvent event = MotionEvent.obtain(ev);
    final int action = MotionEventCompat.getActionMasked(event);
    if (action == MotionEvent.ACTION_DOWN) {
        mNestedOffsetY = 0;
    }
    int eventY = (int) event.getY();
    event.offsetLocation(0, mNestedOffsetY);
    switch (action) {
        case MotionEvent.ACTION_MOVE:
            int deltaY = mLastY - eventY;
            // NestedPreScroll
            if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset)) {
                deltaY -= mScrollConsumed[1];
                mLastY = eventY - mScrollOffset[1];
                event.offsetLocation(0, -mScrollOffset[1]);
                mNestedOffsetY += mScrollOffset[1];
            }
            returnValue = super.onTouchEvent(event);

            // NestedScroll
            if (dispatchNestedScroll(0, mScrollOffset[1], 0, deltaY, mScrollOffset)) {
                event.offsetLocation(0, mScrollOffset[1]);
                mNestedOffsetY += mScrollOffset[1];
                mLastY -= mScrollOffset[1];
            }
            break;
        case MotionEvent.ACTION_DOWN:
            returnValue = super.onTouchEvent(event);
            mLastY = eventY;
            // start NestedScroll
            startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
            returnValue = super.onTouchEvent(event);
            // end NestedScroll
            stopNestedScroll();
            break;
    }
    return returnValue;
}

// Nested Scroll implements
@Override
public void setNestedScrollingEnabled(boolean enabled) {
    mChildHelper.setNestedScrollingEnabled(enabled);
}

@Override
public boolean isNestedScrollingEnabled() {
    return mChildHelper.isNestedScrollingEnabled();
}

@Override
public boolean startNestedScroll(int axes) {
    return mChildHelper.startNestedScroll(axes);
}

@Override
public void stopNestedScroll() {
    mChildHelper.stopNestedScroll();
}

@Override
public boolean hasNestedScrollingParent() {
    return mChildHelper.hasNestedScrollingParent();
}

@Override
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed,
                                    int[] offsetInWindow) {
    return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
}

@Override
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
    return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
}

@Override
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
    return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
}

@Override
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
    return mChildHelper.dispatchNestedPreFling(velocityX, velocityY);
}

}

Объявите NestedWebView вместо объявления WebView внутри NestedScrollView. Например

<com.nestedscrollwebviewexample.NestedWebView
    android:id="@+id/nested_webview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#000000"
    android:fillViewport="true"
    android:focusable="true"
    android:isScrollContainer="false"
    android:visibility="visible"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    app:layout_scrollFlags="scroll|exitUntilCollapsed" />

Вместо объявления Webview вы можете инициализироваться как NestedWebView внутри вашей деятельности

 private NestedWebView mShopWebView;
    mShopWebView = (NestedWebView) findViewById(R.id.url_load_webview);

Надеюсь, что это служит цели.

...