Barre d’outils effilée et animée avec la bibliothèque d’aide à la conception Android

Y a-t-il un moyen de rendre l’animation Collapsing d’Android Design Support Library plus fluide lors du défilement? Lorsque je relâche le défilement, il s’arrête brusquement. Mais ce que je veux, c’est que l’animation continue de s’effondrer même si vous arrêtez de défiler. Android-ObservableScrollView et Scrollable sont les bibliothèques qui se réduisent en douceur.

Vous pouvez utiliser le nouveau composant logiciel enfichable layout_scrollFlag pour un défilement régulier dans les états AppBarLayout. Mais ce que j’ai expérimenté, c’est que lorsque le RecyclerView atteint son sumt, le défilement s’arrête. CollapsingToolbarLayout ne sera pas développé sans un autre défilement. Pour que RecyclerView défile en douceur et développe CollapsingToolbarLayout, j’ai utilisé un ScrollListener sur recyclerview.

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); } } }); 

J’ai utilisé “scroll | exitUntilCollapsed” comme layout_scrollFlags.

  

Celui-ci est assez récent, mais AppBarLayout a été récemment mis à jour pour gérer exactement ce que vous recherchez avec un nouveau layout_scrollFlag appelé snap .

Usage:

 app:layout_scrollFlags="scroll|snap" 

Je vais essayer de chercher ma source et mettre à jour ma réponse quand je le fais.

Edit: Bien sûr, il provient du blog des développeurs Android .

Je le fais via AppBarLayout . en onNestedFling et onNestedPreScroll .

L’astuce consiste à reconsidérer l’événement de fling si l’enfant principal de ScrollingView est proche du début des données dans Adapter.

Source Flinging avec 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, AtsortingbuteSet 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; } } 

Ensuite, définissez le comportement de mise en page en tant FlingBehavior classe FlingBehavior

  

append du code

  app:layout_scrollFlags="scroll|enterAlways" 

dans la vue dans AppBarLayout. C’est mon code de démonstration qui réduit la barre d’outils avec la bibliothèque de support de conception Android.

       

Je travaille aussi sur ce problème et j’ai mis au point peut-être pas de solution très optimisée, mais vous pouvez l’améliorer. Une fois que je l’améliorer, je vais certainement éditer réponse jusqu’à ce que jette un coup d’oeil à cela.

 public abstract class AppBarStateChangeListener implements AppBarLayout.OnOffsetChangedListener { private static final Ssortingng 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; } 

}

Créez cette classe et appelez le code suivant

 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); 

Notez que ne définissez pas la classe annonymique OffsetChangedListener car celle-ci est conservée comme référence faible et sera collectée par GC.

Veuillez explorer ce code et l’améliorer (n’importe qui) et le re-partager.

Essayez d’append le code suivant:

  app:layout_scrollFlags="scroll|snap"