web-dev-qa-db-ja.com

別のCoordinatorLayout内のCoordinatorLayout

別のCorodinatorLayout内のCoordinatorLayout。子ビューをスクロールすると、親CoordinatorLayoutもスクロールします。

coordinatorLayoutに異なるViewPagerを含むFragmentがあり、ScrolltabLayoutを非表示にします

coordinatorLayoutを持つ別のviewPagerがあります。このfragmentは、親フラグメント(parent Coordinator layout)のViewPagerで拡張されます。

問題はonScrollingです。childViewpagerの子フラグメントは、fragmentを非表示にするために必要な親coordinator layoutではなく、tablayoutcoordinator layoutにのみ反映されます。

構造は次のとおりです。

CoordinatorLayout(p) ->(tablayout(p) & ViewPager(p) -> CoordinatorLayout(c)  ->(tablayout(c) & ViewPAger(c) ->recyclerView(cc)))

p -> parent;

c -> child; cc -> child to child

スクロールリサイクラビューの作成方法は、両方のcoordinator layoutに影響するため、toolbar tablayout(p)は非表示になります。

28

私はそれが古い質問であることを知っています。しかし、別のCoordinatorLayoutにあるフラグメントにCoordinatorLayoutを含めるために長い間検索しました。

Dev.bmaxの答えを少し変更して、両方のコーディネーターレイアウトを呼び出し、両方のレイアウトの添付の動作を呼び出しました。

だからここに私の解決策があります。

@SuppressWarnings("unused")
public class NestedCoordinatorLayout extends CoordinatorLayout implements NestedScrollingChild {

    private NestedScrollingChildHelper mChildHelper;

    public NestedCoordinatorLayout(Context context) {
        super(context);
        mChildHelper = new NestedScrollingChildHelper(this);
        setNestedScrollingEnabled(true);
    }

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

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

    @Override
    public boolean onStartNestedScroll(View child, View target, int     nestedScrollAxes) {
        /* Enable the scrolling behavior of our own children */
        boolean tHandled = super.onStartNestedScroll(child, target, nestedScrollAxes);
        /* Enable the scrolling behavior of the parent's other children  */
        return startNestedScroll(nestedScrollAxes) || tHandled;
    }

    @Override
    public void onStopNestedScroll(View target) {
        /* Disable the scrolling behavior of our own children */
        super.onStopNestedScroll(target);
        /* Disable the scrolling behavior of the parent's other children  */
        stopNestedScroll();
    }

    @Override
    public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
        int[][] tConsumed = new int[2][2];
        super.onNestedPreScroll(target, dx, dy, tConsumed[0]);
        dispatchNestedPreScroll(dx, dy, tConsumed[1], null);
        consumed[0] = tConsumed[0][0] + tConsumed[1][0];
        consumed[1] = tConsumed[0][1] + tConsumed[1][1];
    }

    @Override
    public void onNestedScroll(View target, int dxConsumed, int dyConsumed,
                           int dxUnconsumed, int dyUnconsumed) {
        super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
        dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, null);
    }

    @Override
    public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
        boolean tHandled = super.onNestedPreFling(target, velocityX, velocityY);
        return dispatchNestedPreFling(velocityX, velocityY) || tHandled;
    }

    @Override
    public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) {
        boolean tHandled = super.onNestedFling(target, velocityX, velocityY, consumed);
        return dispatchNestedFling(velocityX, velocityY, consumed) || tHandled;
    }

    @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);
    }
}
35
Fabian

ネストされたコーディネーターレイアウトの簡単な実装を次に示します。


/**
 * This variation of CoordinatorLayout also serves as a nested scrolling child,
 * which supports passing nested scrolling operations to it's parent when it's
 * own nested scrolling is locked.
 */
public class NestedCoordinatorLayout extends CoordinatorLayout implements NestedScrollingChild {

    private NestedScrollingChildHelper mChildHelper;
    private volatile boolean mPassToParent;

    public NestedCoordinatorLayout(Context context) {
        super(context);
        mChildHelper = new NestedScrollingChildHelper(this);
        setNestedScrollingEnabled(true);
    }

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

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

    /**
     * Locks the nested scrolling. Further scroll events will
     * be passed to the nested scrolling parent.
     */
    public void lockNestedScrolling() {
        mPassToParent = true;
    }

    /**
     * Unlocks the nested scrolling. Further scroll events will
     * be dispatched to this layout's own scrolling children.
     */
    public void unlockNestedScrolling() {
        mPassToParent = false;
    }

    /*
     * NestedScrollingParent implementation
     */

    @Override
    public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
        /* Enable the scrolling behavior of our own children */
        super.onStartNestedScroll(child, target, nestedScrollAxes);
        /* Enable the scrolling behavior of the parent's other children  */
        startNestedScroll(nestedScrollAxes);
        /* Start tracking the current scroll */
        return true;
    }

    @Override
    public void onStopNestedScroll(View target) {
        /* Disable the scrolling behavior of our own children */
        super.onStopNestedScroll(target);
        /* Disable the scrolling behavior of the parent's other children  */
        stopNestedScroll();
    }

    @Override
    public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
        if (mPassToParent) {
            dispatchNestedPreScroll(dx, dy, consumed, null);
        } else {
            super.onNestedPreScroll(target, dx, dy, consumed);
        }
    }

    @Override
    public void onNestedScroll(View target, int dxConsumed, int dyConsumed,
                               int dxUnconsumed, int dyUnconsumed) {
        if (mPassToParent) {
            dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, null);
        } else {
            super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
        }
    }

    @Override
    public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
        if (mPassToParent) {
            return dispatchNestedPreFling(velocityX, velocityY);
        } else {
            return super.onNestedPreFling(target, velocityX, velocityY);
        }
    }

    @Override
    public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) {
        if (mPassToParent) {
            return dispatchNestedFling(velocityX, velocityY, consumed);
        } else {
            return super.onNestedFling(target, velocityX, velocityY, consumed);
        }
    }

    /*
     * NestedScrollingChild implementation
     */

    @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);
    }
}
9
dev.bmax

私はこれをライブラリにしました、それを見てください GitHubで

使用するのは<NestedScrollCoordinatorLayout>レイアウトで。

4
natario

うまくいけば、これは他の人を助けるでしょう。 preScrollで実装したアイデアは、既に0である場合に親が消費できる量を計算し、super.onNestedPreScrollを呼び出します。

コードは次のとおりです。

import Android.content.Context;
import Android.support.annotation.Nullable;
import Android.support.design.widget.CoordinatorLayout;
import Android.support.v4.view.NestedScrollingChild2;
import Android.support.v4.view.NestedScrollingChildHelper;
import Android.util.AttributeSet;
import Android.view.View;

public class NestedScrollCoordinatorLayout extends CoordinatorLayout implements NestedScrollingChild2 {

  private NestedScrollingChildHelper mChildHelper;

  public NestedScrollCoordinatorLayout(Context context) {
    super(context);
    mChildHelper = new NestedScrollingChildHelper(this);
    setNestedScrollingEnabled(true);
  }

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

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

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

  @Override
  public void setNestedScrollingEnabled(boolean enabled) {
    mChildHelper.setNestedScrollingEnabled(enabled);
  }

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

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

  @Override
  public boolean onStartNestedScroll(View child, View target, int axes, int type) {
    boolean superResult = super.onStartNestedScroll(child, target, axes, type);
    return startNestedScroll(axes, type) || superResult;
  }

  @Override
  public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
    boolean superResult = super.onStartNestedScroll(child, target, nestedScrollAxes);
    return startNestedScroll(nestedScrollAxes) || superResult;
  }

  @Override
  public void onNestedPreScroll(View target, int dx, int dy, int[] consumed, int type) {
    dispatchNestedPreScroll(dx, dy, consumed, null);
    if (consumed[1] == 0) {
      super.onNestedPreScroll(target, dx, dy, consumed, type);
    }
  }

  @Override
  public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
    dispatchNestedPreScroll(dx, dy, consumed, null);
    if (consumed[1] == 0) {
      super.onNestedPreScroll(target, dx, dy, consumed);
    }
  }

  @Override
  public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) {
    super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type);
    dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, null, type);
  }

  @Override
  public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
    super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
    dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, null);
  }

  @Override
  public void onStopNestedScroll(View target, int type) {
    super.onStopNestedScroll(target, type);
    stopNestedScroll(type);
  }

  @Override
  public void onStopNestedScroll(View target) {
    super.onStopNestedScroll(target);
    stopNestedScroll();
  }

  @Override
  public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
    boolean superResult = super.onNestedPreFling(target, velocityX, velocityY);
    return dispatchNestedPreFling(velocityX, velocityY) || superResult;
  }

  @Override
  public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) {
    boolean superResult = super.onNestedFling(target, velocityX, velocityY, consumed);
    return dispatchNestedFling(velocityX, velocityY, consumed) || superResult;
  }

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

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

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

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

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

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

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

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

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

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

こちらもご覧ください Gist on GithHub

2
Kelvin Chandra

残念ながら、これはCoordinatorLayoutでサポートされていません。

NestedScrollingChildHelper.startNestedScroll()およびCoordinatorLayout.onStartNestedScroll()のコードを確認してください。ネストされたスクロールイベントは、内部BehaviorCoordinatorLayoutsのいずれかが消費すると「消費」され、それ以上伝播されません。

0
xizzhu

CHILD CoordinatorLayoutをカスタマイズし、NestedScrollingChildを実装させ(ori coordinatorlayoutは実装しなかった)、いくつかの関数をオーバーライドして、ネストされたスクロールイベントをPARENT CoordinatorLayoutにディスパッチできるようにする必要があります。

0
kevinstyle

リポジトリに ChildCoordinatorLayout を1つ記述しました nestrefresh 。このレポでは、1つのAppBarLayoutをChildCoordinatorLayoutでラップし、プルリフレッシュ動作でChildCoordinatorLayoutのプルリフレッシュも追加します。そして、dyUnConsumedはまず親を、次に子を与えます。これはコードです:

class ChildCoordinatorLayout @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : CoordinatorLayout(context, attrs, defStyleAttr), NestedScrollingChild2 {

    private lateinit var childHelper: NestedScrollingChildHelper

    init {
        init()
    }

    private fun init() {
        childHelper = NestedScrollingChildHelper(this)
        childHelper.isNestedScrollingEnabled = true
    }

    override fun setNestedScrollingEnabled(enabled: Boolean) {
        childHelper.isNestedScrollingEnabled = enabled
    }

    override fun isNestedScrollingEnabled(): Boolean {
        return childHelper.isNestedScrollingEnabled
    }

    override fun startNestedScroll(i: Int, i1: Int): Boolean {
        return childHelper.startNestedScroll(i, i1)
    }

    override fun stopNestedScroll(i: Int) {
        childHelper.stopNestedScroll(i)
    }

    override fun hasNestedScrollingParent(i: Int): Boolean {
        return childHelper.hasNestedScrollingParent()
    }

    override fun dispatchNestedScroll(i: Int, i1: Int, i2: Int, i3: Int, ints: IntArray?, i4: Int): Boolean {
        return childHelper.dispatchNestedScroll(i, i1, i2, i3, ints, i4)
    }

    override fun dispatchNestedPreScroll(i: Int, i1: Int, ints: IntArray?, ints1: IntArray?, i2: Int): Boolean {
        return childHelper.dispatchNestedPreScroll(i, i1, ints, ints1, i2)
    }

    override fun dispatchNestedPreFling(velocityX: Float, velocityY: Float): Boolean {
        return childHelper.dispatchNestedPreFling(velocityX, velocityY)
    }

    override fun dispatchNestedFling(velocityX: Float, velocityY: Float, consumed: Boolean): Boolean {
        return childHelper.dispatchNestedFling(velocityX, velocityY, consumed)
    }

    override fun onStartNestedScroll(child: View, target: View, axes: Int, type: Int): Boolean {
        if (type == TYPE_TOUCH) {
            stopNestedScroll(TYPE_NON_TOUCH)
            ViewCompat.stopNestedScroll(child, TYPE_NON_TOUCH)
        }
        val handle = super.onStartNestedScroll(child, target, axes, type)
        return startNestedScroll(axes, type) || handle
    }

    override fun onStopNestedScroll(target: View, type: Int) {
        super.onStopNestedScroll(target, type)
        stopNestedScroll(type)
    }

    override fun onNestedPreScroll(target: View, dx: Int, dy: Int, consumed: IntArray, type: Int) {
        val thisConsume = IntArray(2)
        dispatchNestedPreScroll(dx, dy, thisConsume, null, type)
        consumed[0] += thisConsume[0]
        consumed[1] += thisConsume[1]
        thisConsume[0] = 0
        thisConsume[1] = 0
        super.onNestedPreScroll(target, dx - consumed[0], dy - consumed[1], thisConsume, type)
        consumed[0] += thisConsume[0]
        consumed[1] += thisConsume[1]

    }

    override fun onNestedScroll(
        target: View,
        dxConsumed: Int,
        dyConsumed: Int,
        dxUnconsumed: Int,
        dyUnconsumed: Int,
        type: Int
    ) {

        val offsetInWindow = IntArray(2)
        target.getLocationInWindow(offsetInWindow)
        val startX = offsetInWindow[0]
        val startY = offsetInWindow[1]
        super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type)
        target.getLocationInWindow(offsetInWindow)
        offsetInWindow[0] -= startX
        offsetInWindow[1] -= startY
        dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed + offsetInWindow[0]
            , dyUnconsumed + offsetInWindow[1], null, type)
    }

    override fun onNestedPreFling(target: View, velocityX: Float, velocityY: Float): Boolean {
        val handled = super.onNestedPreFling(target, velocityX, velocityY)
        return dispatchNestedPreFling(velocityX, velocityY) || handled
    }

    override fun onNestedFling(target: View, velocityX: Float, velocityY: Float, consumed: Boolean): Boolean {
        val handled = super.onNestedFling(target, velocityX, velocityY, consumed)
        return dispatchNestedFling(velocityX, velocityY, consumed) || handled
    }

}
0
CN_tudou