使用Androiddevise支持库平滑animation折叠工具栏
无论如何,使滚动的Androiddevise支持库的Collapsinganimation更平滑吗? 当我释放滚动,它突然停止。 但是我想要的是:即使停止滚动,折叠animation也会顺利地继续。 Android-ObservableScrollView和Scrollable是正在崩溃的图书馆。
您可以使用新的layout_scrollFlag快照在AppBarLayout状态下进行平滑滚动。 但是我所经历的是,当RecyclerView达到顶峰时,滚动停止。 即CollapsingToolbarLayout将不会展开没有另一个滚动。 为了让RecyclerView平滑滚动并展开CollapsingToolbarLayout,我在回收站上使用了ScrollListener。
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { int scrollDy = 0; @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { scrollDy += dy; } @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if(scrollDy==0&&(newState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE)) { AppBarLayout appBarLayout = ((AppBarLayout) view.findViewById(R.id.app_bar)); appBarLayout.setExpanded(true); } } });
我使用了“scroll | exitUntilCollapsed”作为layout_scrollFlags。
<android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapsing_toolbar_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" android:minHeight="80dp" app:layout_collapseMode="none" app:layout_scrollFlags="scroll|exitUntilCollapsed">
这是一个相当新的,但AppBarLayout最近已经更新,以处理你正在寻找一个新的layout_scrollFlag叫做snap
。
用法:
app:layout_scrollFlags="scroll|snap"
我会尽力寻找我的来源,并在我做的时候更新我的答案。
编辑:当然,这是从Android开发人员的博客 。
我正在通过AppBarLayout
来AppBarLayout
。 通过覆盖onNestedFling
和onNestedPreScroll
。
诀窍是如果ScrollingView的顶部的孩子接近适配器中的数据的开始,则重新build立滑动事件。
来源与RecyclerView + AppBarLayout投掷
public final class FlingBehavior extends AppBarLayout.Behavior { private static final int TOP_CHILD_FLING_THRESHOLD = 3; private boolean isPositive; public FlingBehavior() { } public FlingBehavior(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onNestedFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY, boolean consumed) { if (velocityY > 0 && !isPositive || velocityY < 0 && isPositive) { velocityY = velocityY * -1; } if (target instanceof RecyclerView && velocityY < 0) { final RecyclerView recyclerView = (RecyclerView) target; final View firstChild = recyclerView.getChildAt(0); final int childAdapterPosition = recyclerView.getChildAdapterPosition(firstChild); consumed = childAdapterPosition > TOP_CHILD_FLING_THRESHOLD; } return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed); } @Override public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed) { super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed); isPositive = dy > 0; } }
然后将布局行为设置为FlingBehavior
类
<android.support.design.widget.AppBarLayout app:layout_behavior="package.FlingBehavior" android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="250dip" android:fitsSystemWindows="true">
添加代码
app:layout_scrollFlags="scroll|enterAlways"
在AppBarLayout里面的视图中。 这是我的演示代码折叠与Androiddevise支持库的工具栏。
<android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_scrollFlags="scroll|enterAlways"> <bubee.inews.Items.ItemMenu android:id="@+id/itemMenu" android:layout_width="match_parent" android:layout_height="wrap_content" /> </android.support.v7.widget.Toolbar> </android.support.design.widget.AppBarLayout>
我也在研究这个问题,并且想出了可能不是非常优化的解决scheme,但是你可以改进它。一旦我改进它,我一定会编辑答案,直到看看这个。
public abstract class AppBarStateChangeListener implements AppBarLayout.OnOffsetChangedListener { private static final String TAG = "app_AppBarStateChange"; public enum State { EXPANDED, COLLAPSED, IDLE } private State mCurrentState = State.IDLE; private int mInitialPosition = 0; private boolean mWasExpanded; private boolean isAnimating; @Override public final void onOffsetChanged(AppBarLayout appBarLayout, int i) { if (i == 0) { if (mCurrentState != State.EXPANDED) { onStateChanged(appBarLayout, State.EXPANDED); } mCurrentState = State.EXPANDED; mInitialPosition = 0; mWasExpanded = true; Log.d(TAG, "onOffsetChanged 1"); isAnimating = false; appBarLayout.setEnabled(true); } else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) { if (mCurrentState != State.COLLAPSED) { onStateChanged(appBarLayout, State.COLLAPSED); } mCurrentState = State.COLLAPSED; mInitialPosition = appBarLayout.getTotalScrollRange(); mWasExpanded = false; Log.d(TAG, "onOffsetChanged 2"); isAnimating = false; appBarLayout.setEnabled(true); } else { Log.d(TAG, "onOffsetChanged 3"); int diff = Math.abs(Math.abs(i) - mInitialPosition); if(diff >= appBarLayout.getTotalScrollRange()/3 && !isAnimating) { Log.d(TAG, "onOffsetChanged 4"); isAnimating = true; appBarLayout.setEnabled(false); appBarLayout.setExpanded(!mWasExpanded,true); } if (mCurrentState != State.IDLE) { onStateChanged(appBarLayout, State.IDLE); } mCurrentState = State.IDLE; } } public abstract void onStateChanged(AppBarLayout appBarLayout, State state); public State getCurrentState() { return mCurrentState; }
}
创build这个类并调用下面的代码
private AppBarStateChangeListener mAppBarStateChangeListener = new AppBarStateChangeListener() { @Override public void onStateChanged(AppBarLayout appBarLayout, State state) { Log.d(TAG, "ToBeDeletedActivity.onStateChanged :: " + state); if(state == State.EXPANDED || state == State.IDLE) { getSupportActionBar().setTitle(""); } else { getSupportActionBar().setTitle("Hello World"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { mAppBarLayout.setElevation(0); } } } }; mAppBarLayout.addOnOffsetChangedListener(mAppBarStateChangeListener);
请注意,不要设置匿名类OffsetChangedListener,因为这被保留为弱引用,并会被GC收集。我发现自己很难。
请探索此代码并改进(任何人)并重新分享。谢谢
尝试添加以下代码:
app:layout_scrollFlags="scroll|snap"