Android 如何检测在协调布局中停止的嵌套投掷。行为?
如何使用CoordinatorLayout.Behavior检测嵌套的fling是否完全停止?Android 如何检测在协调布局中停止的嵌套投掷。行为?,android,android-support-library,android-coordinatorlayout,Android,Android Support Library,Android Coordinatorlayout,如何使用CoordinatorLayout.Behavior检测嵌套的fling是否完全停止? 没有这样的api可以在回收器视图完全停止时给我回叫。当滚动a时,我试图隐藏a(FAB)时从这个兔子洞开始。根据multiple执行此操作的正确方法是扩展、覆盖onStartNestedScroll和onStopNestedScroll方法,并将您的行为连接到FAB,例如app:layou\u behavior=“com.justingarrick.ui.ScrollAwareFabBehavior”。
没有这样的api可以在回收器视图完全停止时给我回叫。当滚动a时,我试图隐藏a(FAB)时从这个兔子洞开始。根据multiple执行此操作的正确方法是扩展、覆盖
onStartNestedScroll
和onStopNestedScroll
方法,并将您的行为连接到FAB,例如app:layou\u behavior=“com.justingarrick.ui.ScrollAwareFabBehavior”
。这适用于正常(慢速)滚动事件,但在投掷结束时不会调用onStopNestedScroll
目前,似乎有一些公开的抛掷和滚动行为;我的解决方法是为我的RecyclerView实现一个OnScrollListener
,并通过编程方式更改FAB的状态,例如
public class MyFragment extends Fragment {
@Bind(R.id.account_list) RecyclerView recyclerView;
@Bind(R.id.button_fab) FloatingActionButton fab;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_accounts, container, false);
ButterKnife.bind(this, view);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_DRAGGING)
fab.hide(); // or hideFab(), see below
else if (newState == RecyclerView.SCROLL_STATE_IDLE)
fab.show(); // or showFab(), see below
}
});
return view;
}
}
更新:这在99%的时间内都能正常工作,但如果使用设计库22.2.1版中的show()
和hide()
方法,当您尝试在RecyclerView的顶部向上滚动或在RecyclerView的底部向下滚动时,您会遇到问题,因为recycler视图正在从RecyclerView切换状态。滚动\u STATE\u拖动到RecyclerView。滚动\u STATE\u IDLE
的速度太快,会在中创建竞争条件浮动操作按钮honeycombmr1#show()
。因此,要解决这个问题(叹气),如果您不关心动画,您需要切换到setVisibility()
调用,或者在没有竞争条件的情况下重新实现动画,例如
private void hideFab() {
fab.animate().scaleX(0.0F).scaleY(0.0F).alpha(0.0F).setDuration(200L).setInterpolator(new FastOutSlowInInterpolator()).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
fab.setVisibility(View.GONE);
}
});
}
private void showFab() {
fab.animate().scaleX(1.0F).scaleY(1.0F).alpha(1.0F).setDuration(200L).setInterpolator(new FastOutSlowInInterpolator()).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
fab.setVisibility(View.VISIBLE);
}
});
}
我使用ScrollerCompat和ScrollerCompat.fling(..)方法来处理滚动的中间状态。所以我知道滚动何时结束
@Override
public boolean onNestedFling(final CoordinatorLayout coordinatorLayout, final AppBarLayout child, final View target, final float velocityX, final float velocityY, final boolean consumed) {
final int scrollY = target.getScrollY();
final double distance = mFlingHelper.getSplineFlingDistance(velocityY);
fling(
child,
(int) distance + scrollY,
velocityY,
scrollY);
return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed);
}
private void fling(final View pChild, final int pMaxOffset, final float pVelocityY, final int pStartY) {
stopFling(pChild);
mIsFlingRunning = true;
if (mScroller == null) {
mScroller = ScrollerCompat.create(mContext);
}
mScroller.fling(
0, pStartY, // current
0, Math.round(pVelocityY), // velocity.
0, 0, // x
0, pMaxOffset); // y
if (mScroller.computeScrollOffset()) {
mFlingRunnable = new FlingRunnable(pChild);
ViewCompat.postOnAnimation(pChild, mFlingRunnable);
}
}
private void stopFling(final View pChild) {
if (mFlingRunnable != null) {
pChild.removeCallbacks(mFlingRunnable);
mFlingRunnable = null;
}
}
private class FlingRunnable implements Runnable {
private final View mView;
FlingRunnable(final View pView) {
mView = pView;
}
@Override
public void run() {
if (mView != null && mScroller != null) {
if (mScroller.computeScrollOffset()) {
mIsFlingRunning = true;
// Post ourselves so that we run on the next animation
ViewCompat.postOnAnimation(mAppBarLayout, this);
}
} else {
mIsFlingRunning = false;
}
}
}
你不能用SCROLL\u STATE\u IDLE
实现同样的效果吗?在CoordinatorLayout.Behavior中没有像onScrollStateChanged(AblistView视图,int scrollState)这样的方法可以给我scrollState。有一个方法叫做onStopNestedScroll,但它在列表完全停止之前就被调用了。我的意思是onScrollChanged()
对于RecyclerView
感谢您的响应,基本上我是在类内做FAB动画扩展FloatingActionButton。行为叫做ScrollawRefabbeHavior,我如何在这个类中检查RecyclerView的SCROLL\u STATE\u IDLE,而且这个类是作为布局行为传递给FAB的。谢谢你的回复,至少我不是唯一一个面对这个问题的人。聪明的简单解决方案!我只需要在滚动视图中的特定视图可见时显示晶圆厂,而在该视图不在屏幕上时将其隐藏。有了这种行为,就不可能管理好这些放纵行为。。。使用滚动监听器,它可以完美地工作!