Я анимирую панель инструментов, чтобы скрыть / показать. Я использую следующее поведение 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);
}
}
Когда новый экземпляр приложения создается впервые, и нет экземпляра приложения в недавнем приложении, он немного отстает при первой прокрутке, но потом вообще не будет отставания. Когда я уничтожаю экземпляр приложения, нажимая кнопку «Назад» и снова запускаю приложение, задержки нет, но когда я удаляю приложение из недавних приложений и снова запускаю приложение, оно немного отстает только в первом прокрутке. (это происходит в Samsung Galaxy s9)
Дополнение: Когда я тестирую в Google pixel2, лагов нет вообще.
Полный исходный код можно найти здесь: https://github.com/Ali-Rezaei/Contacts/tree/master/app/src/main/java/com/sample/android/contact
Проблема может быть в моем адаптере из-за того, что я выполняю тяжелую работу в потоке пользовательского интерфейса: https://github.com/Ali-Rezaei/Contacts/blob/master/app/src/main/java/com/sample/android/contact/ui/ContactsAdapter.java
Но если я выполняю тяжелую работу в основном потоке , почему это происходит при запуске, а не позже?