recyclerview icon floatingactionbutton example coordinatorlayout android

android - icon - floating action button recyclerview



FloatingActionButton ocultar en lista de desplazamiento (8)

Estoy usando el FloatingActionButton del paquete android.support.design.widget :

<android.support.design.widget.FloatingActionButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentEnd="true" android:layout_marginBottom="20dp" android:layout_marginEnd="16dp" android:clickable="true" android:backgroundTint="@color/primaryColor" android:src="@drawable/ic_search_white_24dp" app:borderWidth="0dp" app:elevation="6dp" app:backgroundTint="@color/primaryColorDark" app:rippleColor="@color/accentColor" />

¿Es posible configurar ese botón para ocultarse con una animación cuando la vista de lista se desplaza hacia abajo y mostrarlo nuevamente cuando la vista de lista se desplaza hacia arriba?


Aquí estoy agregando un relleno adicional para el último elemento de la vista para evitar la superposición del elemento de la lista con el botón de acción flotante

Utilicé esto en el método onBindViewHolder de RecyclerView.Adapter para establecer el margen inferior del último elemento de la lista a 72dp para que se desplace hacia arriba sobre el botón de acción flotante.

Esto no requiere una entrada ficticia en la lista.

@Override public void onBindViewHolder(ViewHolder holder, int position) { // other binding code goes here. if (position + 1 == getItemCount()) { // set bottom margin to 72dp. setBottomMargin(holder.itemView, (int) (72 * Resources.getSystem().getDisplayMetrics().density)); } else { // reset bottom margin back to zero. (your value may be different) setBottomMargin(holder.itemView, 0); } } public static void setBottomMargin(View view, int bottomMargin) { if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) { ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) view.getLayoutParams(); params.setMargins(params.leftMargin, params.topMargin, params.rightMargin, bottomMargin); view.requestLayout(); } }


Aquellos que buscan hacerlo con Recyclerview pueden hacer esto:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){ @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy){ if (dy > 0 ||dy<0 && fab.isShown()) fab.hide(); } @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { if (newState == RecyclerView.SCROLL_STATE_IDLE){ fab.show(); } super.onScrollStateChanged(recyclerView, newState); } });


Según mi opinión, la mejor manera de implementar esto sería la siguiente.

public class ScrollingFABBehavior extends FloatingActionButton.Behavior { private static final String TAG = "ScrollingFABBehavior"; public ScrollingFABBehavior(Context context, AttributeSet attrs) { super(); // Log.e(TAG, "ScrollAwareFABBehavior"); } public boolean onStartNestedScroll(CoordinatorLayout parent, FloatingActionButton child, View directTargetChild, View target, int nestedScrollAxes) { return true; } @Override public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton child, View dependency) { if (dependency instanceof RecyclerView) return true; return false; } @Override public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) { // TODO Auto-generated method stub super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed); //Log.e(TAG, "onNestedScroll called"); if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) { // Log.e(TAG, "child.hide()"); child.hide(); } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) { // Log.e(TAG, "child.show()"); child.show(); } }}

Para una respuesta detallada mira esto. Ocultar FloatingActionButton en el desplazamiento de RecyclerView


Una pequeña mejora en el código de :

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){ @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy){ if (dy<0 && !fab.isShown()) fab.show(); else if(dy>0 && fab.isShown()) fab.hide(); } @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); } });

El botón de acción flotante se oculta cuando se desplaza hacia abajo y se muestra cuando se desplaza hacia arriba.


Ver this Aquí le dice cómo hacer lo que está tratando de lograr. Tienes que usarlo así en un CoordinatorLayout y en ListView :

<android.support.design.widget.CoordinatorLayout android:id="@+id/main_content" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/lvToDoList" android:layout_width="match_parent" android:layout_height="match_parent"></ListView> <android.support.design.widget.FloatingActionButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|right" android:layout_margin="16dp" android:src="@drawable/ic_done" app:layout_anchor="@id/lvToDoList" app:layout_anchorGravity="bottom|right|end" /> </android.support.design.widget.CoordinatorLayout>


hey no es necesario tomar el recyclerview para ocultar automáticamente el botón de acción flotante al desplazarse hacia abajo para este propósito, podemos usar la vista de lista predeterminada con el botón de acción flotante de manera normal, solo realizar modificaciones en el listener.

listview.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { int lastItem = firstVisibleItem + visibleItemCount; if (lastItem == totalItemCount) { fab.setVisibility(View.INVISIBLE); }else { fab.setVisibility(View.VISIBLE); } } });


usando esta clase puede animar fácilmente su FAB, aquí he implementado el método onStopNestedScroll () para mostrar su Fab cada vez que se detiene el desplazamiento. Establecí 1000 milisegundos como demora usando Handler ();

public class FabBehaviour extends CoordinatorLayout.Behavior<FloatingActionButton> { private static final String TAG = "ScrollingFABBehavior"; Handler mHandler; public FabBehaviour(Context context, AttributeSet attrs) { super(); } public FabBehaviour() { super(); } @Override public void onStopNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull final FloatingActionButton child, @NonNull View target, int type) { super.onStopNestedScroll(coordinatorLayout, child, target, type); if (mHandler == null) mHandler = new Handler(); mHandler.postDelayed(new Runnable() { @Override public void run() { child.animate().translationY(0).setInterpolator(new LinearInterpolator()).start(); Log.d("FabAnim", "startHandler()"); } }, 1000); } @Override public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull FloatingActionButton child, @NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) { super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type); if (dyConsumed > 0) { Log.d("Scrolling", "Up"); CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) child.getLayoutParams(); int fab_bottomMargin = layoutParams.bottomMargin; child.animate().translationY(child.getHeight() + fab_bottomMargin).setInterpolator(new LinearInterpolator()).start(); } else if (dyConsumed < 0) { Log.d("Scrolling", "down"); child.animate().translationY(0).setInterpolator(new LinearInterpolator()).start(); } } @Override public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull FloatingActionButton child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) { if (mHandler != null) { mHandler.removeMessages(0); Log.d("Scrolling", "stopHandler()"); } return axes == ViewCompat.SCROLL_AXIS_VERTICAL; } }

tu_layout.xml

<android.support.design.widget.FloatingActionButton android:id="@+id/imageViewYes" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end|right" android:layout_margin="@dimen/fab_margin" android:src="@drawable/ic_yes" app:backgroundTint="@color/white" android:scaleType="center" app:elevation="6dp" app:fabSize="normal" app:layout_behavior="com.your.package.FabBehaviour" app:pressedTranslationZ="12dp" app:rippleColor="@color/gray" />


mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); if (dy > 0 && mFloatingActionButton.getVisibility() == View.VISIBLE) { mFloatingActionButton.hide(); } else if (dy < 0 && mFloatingActionButton.getVisibility() != View.VISIBLE) { mFloatingActionButton.show(); } }});