Modificado al componente de actualización horizontal basado en SwipeRefreshLayout nativo

Hay muchos componentes deslizantes horizontales en Internet, pero todos se implementan por sí mismos. Así que me preguntaba si podría ser perezoso y cambiarlo directamente con el original jaja. El resultado es realmente bueno. Es solo que es posible que ListView no sea compatible. ViewGroup (RecyclerView) son todos posibles. Si desea admitir ListView para implementar el método canChildScrollLeft en OnChildScrollUpCallback que proporcionan para determinar si puede deslizarse de izquierda a derecha, cambié de arriba a izquierda porque es un deslizamiento horizontal.
Primero vaya al código
https://github.com/Darksiderlyd/HSwipeRefreshLayout

El primer paso:
primero mire el diseño del componente desplegable antes de agregarlo en la parte superior, ahora cámbielo y agréguelo a la izquierda, el siguiente es el código modificado:

@Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        final int width = getMeasuredWidth();
        final int height = getMeasuredHeight();
        if (getChildCount() == 0) {
            return;
        }
        if (mTarget == null) {
            ensureTarget();
        }
        if (mTarget == null) {
            return;
        }
        final View child = mTarget;
        final int childLeft = getPaddingLeft();
        final int childTop = getPaddingTop();
        final int childWidth = width - getPaddingLeft() - getPaddingRight();
        final int childHeight = height - getPaddingTop() - getPaddingBottom();
        child.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
        int circleWidth = mCircleView.getMeasuredWidth();
        int circleHeight = mCircleView.getMeasuredHeight();
        mCircleView.layout(mCurrentTargetOffsetLeft, (height / 2 - circleHeight / 2),
                mCurrentTargetOffsetLeft + circleWidth, (height / 2 + circleHeight / 2));
    }

Paso 2:
modificar varios parámetros relacionados con Y, Top y Vertical

 private float mInitialMotionX;
 private float mInitialDownX;

1. Antes de estos dos parámetros, Y se cambió a X porque el deslizamiento lateral está relacionado con el eje X y no tiene nada que ver con el eje Y.
Luego modifique la posición de los dos parámetros relacionados con getY cambiado a X.
Estos métodos se encuentran principalmente en los siguientes métodos:

onInterceptTouchEvent()
onTouchEvent()

//此方法中的dy改为dx以下为修改后方法
@Override
public void onNestedScroll(final View target, final int dxConsumed, final int dyConsumed,
                           final int dxUnconsumed, final int dyUnconsumed) {
    // Dispatch up to the nested parent first
    dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed,
            mParentOffsetInWindow);

    // This is a bit of a hack. Nested scrolling works from the bottom up, and as we are
    // sometimes between two nested scrolling views, we need a way to be able to know when any
    // nested scrolling parent has stopped handling events. We do that by using the
    // 'offset in window 'functionality to see if we have been moved from the event.
    // This is a decent indication of whether we should take over theeventstream or not.
    final int dx = dxUnconsumed + mParentOffsetInWindow[0];
   if (dx < 0 && !canChildScrollUp()) {
        mTotalUnconsumed += Math.abs(dx);
        moveSpinner(mTotalUnconsumed);
    }
}
 
 
 @Override
 public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
    // If we are in the middle of consuming, a scroll, then we want to move the spinner back up
    // before allowing the list to scroll
    if (dx > 0 && mTotalUnconsumed > 0) {
        if (dx > mTotalUnconsumed) {
            consumed[0] = dx - (int) mTotalUnconsumed;
            mTotalUnconsumed = 0;
           } else {
               mTotalUnconsumed -= dx;
               consumed[0] = dx;
           }
           moveSpinner(mTotalUnconsumed);
    }

    // If a client layout is using a custom start position for the circle
    // view, they mean to hide it again before scrolling the child view
    // If we get back to mTotalUnconsumed == 0 and there is more to go, hide
    // the circle so it isn't exposed if its blocking content is moved
     if (mUsingCustomStart && dx > 0 && mTotalUnconsumed == 0
             && Math.abs(dx - consumed[0]) > 0) {
         mCircleView.setVisibility(View.GONE);
    }

     // Now let our nested parent consume the leftovers
     final int[] parentConsumed = mParentScrollConsumed;
     if (dispatchNestedPreScroll(dx - consumed[0], dy - consumed[1], parentConsumed, null)) {
         consumed[0] += parentConsumed[0];
         consumed[1] += parentConsumed[1];
    }
}

2. Cambie todo View.getTop () a View.getLeft ():

mCircleView.getLeft()

3. Modifique los parámetros relacionados con Vertical, modifique canScrollVertically (parámetros menores que 0 para deslizar de arriba hacia abajo, mayores que cero de abajo hacia arriba) a canScrollHorizontally (parámetros menores que 0 para deslizar de izquierda a derecha, mayores que cero de derecha a izquierda), SCROLL_AXIS_VERTICAL se modifica a SCROLL_AXIS_HORIZONTAL. En el siguiente código, se elimina el juicio de ListView. Mirando el código fuente, solo juzga si puede deslizarse hacia arriba y hacia abajo, por lo que si desea adaptarse a ListView, debe implementar el método mChildScrollUpCallback.canChildScrollLeft

public boolean canChildScrollUp() {
        if (mChildScrollUpCallback != null) {
            return mChildScrollUpCallback.canChildScrollLeft(this, mTarget);
        }
//        if (mTarget instanceof ListView) {
//            return ListViewCompat.canScrollList((ListView) mTarget, -1);
            return mChildScrollUpCallback.canChildScrollLeft(this, mTarget);
//        }
        return mTarget.canScrollHorizontally(-1);
}
    
// NestedScrollingParent
 @Override
 public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
     return isEnabled() && !mReturningToStart && !mRefreshing
             && (nestedScrollAxes & ViewCompat.SCROLL_AXIS_HORIZONTAL) != 0;
 }

@Override
public void onNestedScrollAccepted(View child, View target, int axes) {
    // Reset the counter of how much leftover scroll needs to beconsumed.
       mNestedScrollingParentHelper.onNestedScrollAccepted(child, target, axes);
       // Dispatch up to the nested parent
       startNestedScroll(axes & ViewCompat.SCROLL_AXIS_HORIZONTAL);
       mTotalUnconsumed = 0;
       mNestedScrollInProgress = true;
   }

4. Después de la modificación, probé el efecto. Siento que el componente desplegable es que la distancia del círculo no está en armonía con el deslizamiento del dedo. Mira el código fuente, hay un DRAG_RATE (coeficiente de amortiguación) y este parámetro se cambia un poco más.

referencia:

https://www.jianshu.com/p/1f0d44faed5f

https://blog.csdn.net/birthmarkqiqi/article/details/79564289

Supongo que te gusta

Origin blog.csdn.net/u011148116/article/details/103312994
Recomendado
Clasificación