我正在为工具栏设置动画,以便隐藏/显示。我正在使用以下CoordinatorLayout行为:
public abstract class QuickHideBehavior extends CoordinatorLayout.Behavior<View> {
private static final int DIRECTION_UP = 1;
private static final int DIRECTION_DOWN = -1;
/* Tracking last threshold crossed */
private int mScrollTrigger;
private ObjectAnimator mAnimator;
private View mRecyclerView;
protected abstract void directionUpScrolling(View recyclerView);
protected abstract void directionDownScrolling(View recyclerView);
protected abstract float getTargetHideValue(ViewGroup parent, View target);
//Required to instantiate as a default behavior
@SuppressWarnings("unused")
public QuickHideBehavior() {
}
//Required to attach behavior via XML
@SuppressWarnings("unused")
public QuickHideBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
//Called before a nested scroll event. Return true to declare interest
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout,
View child, View directTargetChild, View target,
int nestedScrollAxes, int type) {
//We have to declare interest in the scroll to receive further events
return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
}
//Called after the scrolling child handles the fling
@Override
public boolean onNestedFling(CoordinatorLayout coordinatorLayout,
View child, View target, float velocityX, float velocityY,
boolean consumed) {
if(mRecyclerView == null) {
mRecyclerView = target.findViewById(R.id.recyclerView);
}
//We only care when the target view is already handling the fling
if (consumed) {
if (velocityY > 0 && mScrollTrigger != DIRECTION_UP) {
mScrollTrigger = DIRECTION_UP;
restartAnimator(child, getTargetHideValue(coordinatorLayout, child));
directionUpScrolling(mRecyclerView);
} else if (velocityY < 0 && mScrollTrigger != DIRECTION_DOWN) {
mScrollTrigger = DIRECTION_DOWN;
restartAnimator(child, 0f);
directionDownScrolling(mRecyclerView);
}
}
return false;
}
/* Helper Methods */
//Helper to trigger hide/show animation
private void restartAnimator(View target, float value) {
if (mAnimator != null) {
mAnimator.cancel();
mAnimator = null;
}
mAnimator = ObjectAnimator
.ofFloat(target, View.TRANSLATION_Y, value)
.setDuration(250);
mAnimator.start();
}
}
AppBar有一个子类:
public class QuickHideAppBarBehavior extends QuickHideBehavior {
private int actionBarHeight;
//Required to instantiate as a default behavior
@SuppressWarnings("unused")
public QuickHideAppBarBehavior() {
}
//Required to attach behavior via XML
@SuppressWarnings("unused")
public QuickHideAppBarBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
// Calculate ActionBar height
TypedValue tv = new TypedValue();
actionBarHeight = context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true) ?
TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics()) :
(int) context.getResources().getDimension(R.dimen.dimen_recycler_view_spacing);
}
@Override
protected float getTargetHideValue(ViewGroup parent, View target) {
return -target.getHeight();
}
@Override
protected void directionUpScrolling(View recyclerView) {
recyclerView.setPadding(0, 0, 0, 0);
}
@Override
protected void directionDownScrolling(View recyclerView) {
recyclerView.setPadding(0, actionBarHeight, 0, 0);
}
}
第一次创建新的应用程序实例,而在最近的应用程序中没有该应用程序实例时,它在第一次滚动时会有些滞后,但以后再没有滞后。当我通过单击“后退”按钮销毁应用程序实例并再次启动应用程序时,没有滞后,但是当我从最近的应用程序中删除该应用程序并再次启动该应用程序时,仅在第一次滚动中它就滞后了一点。 (它发生在三星Galaxy s9中)
附录:当我在Google pixel2中进行测试时,完全没有滞后。
完整的源代码可以在这里找到:https://github.com/Ali-Rezaei/Contacts/tree/master/app/src/main/java/com/sample/android/contact
问题可能出在我的适配器上,我在UI线程中做了很多工作:https://github.com/Ali-Rezaei/Contacts/blob/master/app/src/main/java/com/sample/android/contact/ui/ContactsAdapter.java
但是,如果我在主线程中做了繁重的工作,为什么它只在开始时发生而不在以后发生?