Pra*_*abs 31 android android-viewpager android-coordinatorlayout android-appbarlayout
CorodinatorLayout在另一个内部CoordinatorLayout,滚动子视图也应该滚动父CoordinatorLayout.
我有一个coordinatorLayout与ViewPager包含不同Fragment,使得在Scroll将隐藏tabLayout
我有另一个coordinatorLayout有viewPager.这fragment是ViewPager父片段(父母Coordinator layout)的膨胀.
问题是onScrolling子片段childViewpager只反映在coordinator layout孩子fragment而不是父母coordinator layout,我需要做的是隐藏tablayout.
结构是:
CoordinatorLayout(p) ->(tablayout(p) & ViewPager(p) -> CoordinatorLayout(c) ->(tablayout(c) & ViewPAger(c) ->recyclerView(cc)))
p -> parent;
c -> child; cc -> child to child
Run Code Online (Sandbox Code Playgroud)
如何在滚动回收器视图上进行操作将影响协调器布局,以便工具栏tablayout(p)将被隐藏.
Fab*_*ian 37
我知道这是一个老问题.但是我搜索了很长时间才将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);
}
}
Run Code Online (Sandbox Code Playgroud)
dev*_*max 11
这是嵌套协调器布局的简单实现.
/**
* 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);
}
}
Run Code Online (Sandbox Code Playgroud)
NestedCoordinator Layout 的Kotlin 版本,可与基于@fabian answer 的NestedCoordinatorLayouts 的多点 scrollFlags 一起使用。
您将看到的行为是这样的:
和NestedCoordinatorLayout 实现:
import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.NestedScrollingChild
import androidx.core.view.NestedScrollingChildHelper
class NestedCoordinatorLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : CoordinatorLayout(context, attrs, defStyleAttr), NestedScrollingChild {
private var mChildHelper: NestedScrollingChildHelper = NestedScrollingChildHelper(this)
init {
isNestedScrollingEnabled = true
}
override fun onNestedPreScroll(
target: View,
dx: Int,
dy: Int,
consumed: IntArray,
type: Int
) {
val tConsumed = Array(2) { IntArray(2) }
super.onNestedPreScroll(target, dx, dy, consumed, type)
dispatchNestedPreScroll(dx, dy, tConsumed[1], null)
consumed[0] = tConsumed[0][0] + tConsumed[1][0]
consumed[1] = tConsumed[0][1] + tConsumed[1][1]
}
override fun onNestedScroll(
target: View,
dxConsumed: Int,
dyConsumed: Int,
dxUnconsumed: Int,
dyUnconsumed: Int,
type: Int
) {
super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type)
dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, null)
}
override fun onStopNestedScroll(target: View, type: Int) {
/* Disable the scrolling behavior of our own children */
super.onStopNestedScroll(target, type)
/* Disable the scrolling behavior of the parent's other children */
stopNestedScroll()
}
override fun onStartNestedScroll(child: View, target: View, nestedScrollAxes: Int, type: Int): Boolean {
/* Enable the scrolling behavior of our own children */
val tHandled = super.onStartNestedScroll(child, target, nestedScrollAxes, type)
/* Enable the scrolling behavior of the parent's other children */
return startNestedScroll(nestedScrollAxes) || tHandled
}
override fun onStartNestedScroll(child: View, target: View, nestedScrollAxes: Int): Boolean {
/* Enable the scrolling behavior of our own children */
val tHandled = super.onStartNestedScroll(child, target, nestedScrollAxes)
/* Enable the scrolling behavior of the parent's other children */
return startNestedScroll(nestedScrollAxes) || tHandled
}
override fun onStopNestedScroll(target: View) {
/* Disable the scrolling behavior of our own children */
super.onStopNestedScroll(target)
/* Disable the scrolling behavior of the parent's other children */
stopNestedScroll()
}
override fun onNestedPreScroll(target: View, dx: Int, dy: Int, consumed: IntArray) {
val tConsumed = Array(2) { IntArray(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 fun onNestedScroll(
target: View,
dxConsumed: Int,
dyConsumed: Int,
dxUnconsumed: Int,
dyUnconsumed: Int
) {
super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed)
dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, null)
}
override fun onNestedPreFling(
target: View,
velocityX: Float,
velocityY: Float
): Boolean {
val tHandled = super.onNestedPreFling(target, velocityX, velocityY)
return dispatchNestedPreFling(velocityX, velocityY) || tHandled
}
override fun onNestedFling(
target: View,
velocityX: Float,
velocityY: Float,
consumed: Boolean
): Boolean {
val tHandled = super.onNestedFling(target, velocityX, velocityY, consumed)
return dispatchNestedFling(velocityX, velocityY, consumed) || tHandled
}
override fun isNestedScrollingEnabled(): Boolean {
return mChildHelper.isNestedScrollingEnabled
}
override fun setNestedScrollingEnabled(enabled: Boolean) {
mChildHelper.isNestedScrollingEnabled = enabled
}
override fun startNestedScroll(axes: Int): Boolean {
return mChildHelper.startNestedScroll(axes)
}
override fun stopNestedScroll() {
mChildHelper.stopNestedScroll()
}
override fun hasNestedScrollingParent() = mChildHelper.hasNestedScrollingParent()
override fun dispatchNestedScroll(
dxConsumed: Int,
dyConsumed: Int,
dxUnconsumed: Int,
dyUnconsumed: Int,
offsetInWindow: IntArray?
): Boolean {
return mChildHelper.dispatchNestedScroll(
dxConsumed, dyConsumed, dxUnconsumed,
dyUnconsumed, offsetInWindow
)
}
override fun dispatchNestedPreScroll(
dx: Int,
dy: Int,
consumed: IntArray?,
offsetInWindow: IntArray?
): Boolean {
return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow)
}
override fun dispatchNestedFling(
velocityX: Float,
velocityY: Float,
consumed: Boolean
): Boolean {
return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed)
}
override fun dispatchNestedPreFling(velocityX: Float, velocityY: Float): Boolean {
return mChildHelper.dispatchNestedPreFling(velocityX, velocityY)
}
}
Run Code Online (Sandbox Code Playgroud)
你的XML文件实现是这样的:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.appbar.AppBarLayout>
<androidx.appcompat.widget.Toolbar
android:id="@+id/firstScrollingToolbar"
app:layout_scrollFlags="snap|scroll|enterAlways"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.coordinatorlayout.widget.CoordinatorLayout
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<com.google.android.material.appbar.AppBarLayout>
<androidx.appcompat.widget.Toolbar
android:id="@+id/tabLayout"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.AppBarLayout>
<widget.NestedCoordinatorLayout
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<ViewPager
android:id="@+id/chipsViewPager"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<com.google.android.material.appbar.AppBarLayout>
<androidx.appcompat.widget.Toolbar
android:id="@+id/switchToolbar"
app:layout_scrollFlags="enterAlways|snap|scroll">
<androidx.appcompat.widget.SwitchCompat />
</androidx.appcompat.widget.Toolbar>
<androidx.appcompat.widget.Toolbar
android:id="@+id/chipsTabLayout"
app:layout_collapseMode="pin"/>
</com.google.android.material.appbar.AppBarLayout>
</widget.NestedCoordinatorLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Run Code Online (Sandbox Code Playgroud)
这是已实现的布局层次结构的可视化视图:
该视频可以让您更好地了解 Android 视图层次结构的实际工作方式。
小智 5
希望这会对其他人有所帮助。我在 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);
}
}Run Code Online (Sandbox Code Playgroud)
另请参阅GithHub 上的这个要点
不幸的是,这不受CoordinatorLayout.
NestedScrollingChildHelper.startNestedScroll()检查和中的代码,如果您的内部对象CoordinatorLayout.onStartNestedScroll()之一消耗了嵌套滚动事件,则嵌套滚动事件将被“消耗”,并且不会进一步传播。BehaviorCoordinatorLayout
| 归档时间: |
|
| 查看次数: |
9548 次 |
| 最近记录: |