- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 CoordinatorLayout 和 AppBarLayout 构建以下布局:
| View 1(页眉)|
| View 2 ----------|
|回收站 View --- |
我想要实现的行为如下:
这是我作为概念验证创建的测试布局。
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/view1"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:text="TEST TITLE"
android:textSize="50sp"
app:layout_scrollFlags="scroll|enterAlways|snap" />
<TextView
android:id="@+id/view2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TEST TEST TEST TEST TEST TEST TEST TEST"
android:textSize="70sp"
android:minHeight="50dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed" />
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android:support.design.widget.CoordinatorLayout>
我创建了一个测试适配器以在 RV 中添加几个 TextView 项目(这里没什么特别的)。当我运行代码时,它实际上并没有按预期工作。
向下滚动时,我确认 View 1 已完全折叠。
向下滚动更多。 View 2 折叠直到达到 minHeight。之后 RV 开始滚动。到目前为止,这是按预期工作的。
我查看了 AppBarLayout 实现,问题似乎是因为 AppBarLayout 根据 scrollFlags 计算整个 View 的滚动范围,并根据滚动偏移量偏移整个 View ,而不是更新每个 subview 。
有谁知道是否有任何变通方法或开源库可以解决此问题?它不一定是 CoordinatorLayout/AppBarLayout 方法,但我需要产生行为。
提前谢谢你。
最佳答案
好吧,我自己找到了解决方案,并决定将我的解决方案发布给有类似问题的人。
解决方案是创建一个 NestedCoordinatorLayout,它通过实现 NestedScollingChild 来扩展 CoordinatorLayout,这样我们就可以在两个 AppBarLayout 之间进行交互。我在这篇文章中引用了 NestedScrollView 源代码和答案,https://stackoverflow.com/a/36881816/6272520 ,但我必须做一些更改才能使其按我想要的方式工作。
这是 NestedCoordinatorLayout 的代码。
public class NestedCoordinatorLayout extends CoordinatorLayout implements NestedScrollingChild {
private final NestedScrollingChildHelper scrollingChildHelper;
private final int[] parentOffsetInWindow = new int[2];
private final int[] parentScrollConsumed = new int[2];
public NestedCoordinatorLayout(Context context) {
this(context, null);
}
public NestedCoordinatorLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public NestedCoordinatorLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
scrollingChildHelper = new NestedScrollingChildHelper(this);
setNestedScrollingEnabled(true);
}
//NestedScrollingChild
@Override
public void setNestedScrollingEnabled(boolean enabled) {
scrollingChildHelper.setNestedScrollingEnabled(enabled);
}
@Override
public boolean isNestedScrollingEnabled() {
return scrollingChildHelper.isNestedScrollingEnabled();
}
@Override
public boolean startNestedScroll(int axes) {
return scrollingChildHelper.startNestedScroll(axes);
}
@Override
public void stopNestedScroll() {
scrollingChildHelper.stopNestedScroll();
}
@Override
public boolean hasNestedScrollingParent() {
return scrollingChildHelper.hasNestedScrollingParent();
}
@Override
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed,
int dyUnconsumed, int[] offsetInWindow) {
return scrollingChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
}
@Override
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
return scrollingChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
}
@Override
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
return scrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
}
@Override
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
return scrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY);
}
//NestedScrollingParent
@Override
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
scrollingChildHelper.startNestedScroll(nestedScrollAxes);
return super.onStartNestedScroll(child, target, nestedScrollAxes);
}
@Override
public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
final int[] parentConsumed = parentScrollConsumed;
//This is where the most important change happens.
//During the prescroll, we want to decrease dx/dy.
//This will make sure the top bar gets the scroll event first.
if (dispatchNestedPreScroll(dx, dy, parentConsumed, null)) {
dx -= parentConsumed[0];
dy -= parentConsumed[1];
consumed[0] += parentConsumed[0];
consumed[1] += parentConsumed[1];
}
super.onNestedPreScroll(target, dx, dy, consumed);
}
@Override
public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, parentOffsetInWindow);
super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
}
@Override
public void onStopNestedScroll(View target) {
scrollingChildHelper.onStopNestedScroll(target);
super.onStopNestedScroll(target);
}
@Override
public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) {
scrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
return super.onNestedFling(target, velocityX, velocityY, consumed);
}
@Override
public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
scrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY);
return super.onNestedPreFling(target, velocityX, velocityY);
}
@Override
public void onNestedScrollAccepted(View child, View target, int axes) {
super.onNestedScrollAccepted(child, target, axes);
startNestedScroll(axes & ViewCompat.SCROLL_AXIS_VERTICAL);
}
}
更新后的 xml 文件如下所示:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar_layout_for_view1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/view1"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:text="TEST TITLE"
android:background="@android:color/white"
android:textSize="50sp"
app:layout_scrollFlags="scroll|enterAlways|snap" />
</android.support.design.widget.AppBarLayout>
<!-- Consider this like a NestedScrollView.
You need to have a scrolling behavior -->
<NestedCoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar_layout_for_view2"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/view2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="50dp"
android:text="TEST TEST TEST TEST TEST TEST TEST TEST"
android:textSize="70sp"
app:layout_scrollFlags="scroll|exitUntilCollapsed" />
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</NestedCoordinatorLayout>
</android.support.design.widget.CoordinatorLayout>
关于android - 在 AppBarLayout 中使用带有 enterAlways scrollFlag 的 View 和带有 exitUntilCollapsed scrollFlag 的另一个 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36944457/
我正在尝试使用 CoordinatorLayout 和 AppBarLayout 构建以下布局: | View 1(页眉)| | View 2 ----------| |回收站 View --- |
场景: 当其中一个toolbar消失时,第二个toolbar会适配第一个toolbar的scrollFlag , 而不是它自己的 scrollFlag! 注意: 只有当其中一个工具栏消失时才会发生奇怪
我正在尝试了解 CollapsingToolbarLayout,它有一些值设置为 scrollFlags 以控制其中的 View 如何折叠。任何人都可以清楚地划分这些标志之间的区别: 滚动 总是进入
如果在 Toolbar 的 app:layout_scrollFlags 值 scroll 处移除,则内容将移动到顶部。看截图 这是我的布局:
我是一名优秀的程序员,十分优秀!