Diseño de soporte para Android: BottomNavigationView

Estoy tratando de lograr algo como esto https://material.google.com/components/bottom-navigation.html#bottom-navigation-behavior

Pero la vista de reciclador se esconde debajo de la barra de herramientas y no hay efecto en BottomNavigationView

A continuación se muestra mi código

activity_main.xml

<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context=".MainActivity"> <android.support.design.widget.AppBarLayout android:id="@+id/app_bar_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:layout_scrollFlags="scroll|enterAlways" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> </android.support.design.widget.AppBarLayout> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.BottomNavigationView android:id="@+id/nm_bottom" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:background="@color/colorPrimaryDark" android:foregroundTint="@color/colorAccent" app:itemIconTint="@android:color/white" app:itemTextColor="@android:color/white" app:menu="@menu/nav_menu" /> <android.support.v7.widget.RecyclerView android:id="@+id/rv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/nm_bottom" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> </RelativeLayout> </android.support.design.widget.CoordinatorLayout> 

item.xml

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" xmlns:app="http://schemas.android.com/apk/res-auto" android:padding="4dp"> <android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" app:cardElevation="2dp"> <RelativeLayout android:layout_width="fill_parent" android:layout_height="?android:attr/listPreferredItemHeight" android:padding="4dp"> <ImageView android:id="@+id/icon" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentBottom="true" android:layout_alignParentTop="true" android:layout_marginRight="6dip" android:contentDescription="TODO" android:src="@drawable/ic_storage" /> <TextView android:id="@+id/secondLine" android:layout_width="fill_parent" android:layout_height="26dip" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_toRightOf="@id/icon" android:ellipsize="marquee" android:text="Description" android:textSize="12sp" /> <TextView android:id="@+id/firstLine" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_above="@id/secondLine" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_alignWithParentIfMissing="true" android:layout_toRightOf="@id/icon" android:gravity="center_vertical" android:text="Example application" android:textSize="16sp" /> </RelativeLayout> </android.support.v7.widget.CardView> </FrameLayout> public class MainActivity extends AppCompatActivity implements BottomNavigationView.OnNavigationItemSelectedListener { private static final Logger logger = Logger.getLogger(MainActivity.class.getSimpleName()); private BottomNavigationView navigationView; private RecyclerView mRecyclerView; private MyAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initViews(); } private void initViews() { navigationView = (BottomNavigationView) findViewById(R.id.nm_bottom); navigationView.setOnNavigationItemSelectedListener(this); mRecyclerView = (RecyclerView) findViewById(R.id.rv); // use this setting to improve performance if you know that changes // in content do not change the layout size of the RecyclerView mRecyclerView.setHasFixedSize(true); // use a linear layout manager LinearLayoutManager mLayoutManager = new LinearLayoutManager(this); mRecyclerView.setLayoutManager(mLayoutManager); // specify an adapter (see also next example) List<String> myDataset = new ArrayList<>(); for (int i = 0; i < 100; i++) { myDataset.add("Index #" + i); } mAdapter = new MyAdapter(myDataset); mRecyclerView.setAdapter(mAdapter); } @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { return false; } } public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { private List<String> mDataset; // Provide a reference to the views for each data item // Complex data items may need more than one view per item, and // you provide access to all the views for a data item in a view holder public class ViewHolder extends RecyclerView.ViewHolder { // each data item is just a string in this case public TextView txtHeader; public TextView txtFooter; public ViewHolder(View v) { super(v); txtHeader = (TextView) v.findViewById(R.id.firstLine); txtFooter = (TextView) v.findViewById(R.id.secondLine); } } public void add(int position, String item) { mDataset.add(position, item); notifyItemInserted(position); } public void remove(String item) { int position = mDataset.indexOf(item); mDataset.remove(position); notifyItemRemoved(position); } // Provide a suitable constructor (depends on the kind of dataset) public MyAdapter(List<String> myDataset) { mDataset = myDataset; } // Create new views (invoked by the layout manager) @Override public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // create a new view View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler_view, parent, false); // set the view's size, margins, paddings and layout parameters ViewHolder vh = new ViewHolder(v); return vh; } // Replace the contents of a view (invoked by the layout manager) @Override public void onBindViewHolder(ViewHolder holder, int position) { // - get element from your dataset at this position // - replace the contents of the view with that element final String name = mDataset.get(position); holder.txtHeader.setText(mDataset.get(position)); holder.txtHeader.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { remove(name); } }); holder.txtFooter.setText("Footer: " + mDataset.get(position)); } // Return the size of your dataset (invoked by the layout manager) @Override public int getItemCount() { return mDataset.size(); } } 

Edit: Este es un ejemplo simple que muestra cómo implementar el comportamiento de desplazamiento https://github.com/sjthn/BottomNavigationViewBehavior

Cambie su XML a esto:

 <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context=".MainActivity"> <android.support.design.widget.AppBarLayout android:id="@+id/app_bar_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:layout_scrollFlags="scroll|enterAlways" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:title="@string/app_name" /> </android.support.design.widget.AppBarLayout> <android.support.v7.widget.RecyclerView android:id="@+id/rv" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> <android.support.design.widget.BottomNavigationView android:id="@+id/nm_bottom" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorPrimaryDark" android:foregroundTint="@color/colorAccent" app:itemIconTint="@android:color/white" app:itemTextColor="@android:color/white" app:layout_anchor="@+id/rv" app:layout_anchorGravity="bottom" app:menu="@menu/nav_menu" /> </android.support.design.widget.CoordinatorLayout> 

Así que con poca ayuda de @Srijith soy capaz de animar la forma en que se da en el enlace.

Parte de esta respuesta es

 public class BottomNavigationBehavior<V extends View> extends VerticalScrollingBehavior<V> { private static final Interpolator INTERPOLATOR = new LinearOutSlowInInterpolator(); private int mBottomNavigationViewId; private boolean hidden = false; private ViewPropertyAnimatorCompat mTranslationAnimator; private BottomNavigationView navigationView; private View mTabsHolder; public BottomNavigationBehavior() { super(); } public BottomNavigationBehavior(Context context, AttributeSet attrs) { super(context, attrs); mBottomNavigationViewId = R.id.nm_bottom; } @Override public boolean onLayoutChild(CoordinatorLayout parent, V child, int layoutDirection) { boolean layoutChild = super.onLayoutChild(parent, child, layoutDirection); if (navigationView == null && mBottomNavigationViewId != View.NO_ID) { navigationView = findTabLayout(child); getTabsHolder(); } return layoutChild; } private BottomNavigationView findTabLayout(View child) { return (BottomNavigationView) child.findViewById(mBottomNavigationViewId); } @Override public void onNestedVerticalOverScroll(CoordinatorLayout coordinatorLayout, V child, @ScrollDirection int direction, int currentOverScroll, int totalOverScroll) { } @Override public void onDirectionNestedPreScroll(CoordinatorLayout coordinatorLayout, V child, View target, int dx, int dy, int[] consumed, @ScrollDirection int scrollDirection) { handleDirection(child, scrollDirection); } private void handleDirection(V child, int scrollDirection) { if (scrollDirection == ScrollDirection.SCROLL_DIRECTION_DOWN && hidden) { hidden = false; animateOffset(child, 0); } else if (scrollDirection == ScrollDirection.SCROLL_DIRECTION_UP && !hidden) { hidden = true; animateOffset(child, child.getHeight()); } } @Override protected boolean onNestedDirectionFling(CoordinatorLayout coordinatorLayout, V child, View target, float velocityX, float velocityY, @ScrollDirection int scrollDirection) { handleDirection(child, scrollDirection); return true; } private void animateOffset(final V child, final int offset) { ensureOrCancelAnimator(child); mTranslationAnimator.translationY(offset).start(); animateTabsHolder(offset); } private void animateTabsHolder(int offset) { if (mTabsHolder != null) { offset = offset > 0 ? 0 : 1; ViewCompat.animate(mTabsHolder).alpha(offset).setDuration(200).start(); } } private void ensureOrCancelAnimator(V child) { if (mTranslationAnimator == null) { mTranslationAnimator = ViewCompat.animate(child); mTranslationAnimator.setDuration(100); mTranslationAnimator.setInterpolator(INTERPOLATOR); } else { mTranslationAnimator.cancel(); } } private void getTabsHolder() { if (navigationView != null) { mTabsHolder = navigationView.getChildAt(0); } } public static <V extends View> BottomNavigationBehavior<V> from(V view) { ViewGroup.LayoutParams params = view.getLayoutParams(); if (!(params instanceof CoordinatorLayout.LayoutParams)) { throw new IllegalArgumentException("The view is not a child of CoordinatorLayout"); } CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) params) .getBehavior(); if (!(behavior instanceof BottomNavigationBehavior)) { throw new IllegalArgumentException( "The view is not associated with ottomNavigationBehavior"); } return (BottomNavigationBehavior<V>) behavior; } public void setTabLayoutId(@IdRes int tabId) { this.mBottomNavigationViewId = tabId; } } public abstract class VerticalScrollingBehavior<V extends View> extends CoordinatorLayout.Behavior<V> { private int mTotalDyUnconsumed = 0; private int mTotalDy = 0; @ScrollDirection private int mOverScrollDirection = ScrollDirection.SCROLL_NONE; @ScrollDirection private int mScrollDirection = ScrollDirection.SCROLL_NONE; public VerticalScrollingBehavior(Context context, AttributeSet attrs) { super(context, attrs); } public VerticalScrollingBehavior() { super(); } @Retention(RetentionPolicy.SOURCE) @IntDef({ScrollDirection.SCROLL_DIRECTION_UP, ScrollDirection.SCROLL_DIRECTION_DOWN}) public @interface ScrollDirection { int SCROLL_DIRECTION_UP = 1; int SCROLL_DIRECTION_DOWN = -1; int SCROLL_NONE = 0; } /* @return Overscroll direction: SCROLL_DIRECTION_UP, CROLL_DIRECTION_DOWN, SCROLL_NONE */ @ScrollDirection public int getOverScrollDirection() { return mOverScrollDirection; } /** * @return Scroll direction: SCROLL_DIRECTION_UP, SCROLL_DIRECTION_DOWN, SCROLL_NONE */ @ScrollDirection public int getScrollDirection() { return mScrollDirection; } /** * @param coordinatorLayout * @param child * @param direction Direction of the overscroll: SCROLL_DIRECTION_UP, SCROLL_DIRECTION_DOWN * @param currentOverScroll Unconsumed value, negative or positive based on the direction; * @param totalOverScroll Cumulative value for current direction */ public abstract void onNestedVerticalOverScroll(CoordinatorLayout coordinatorLayout, V child, @ScrollDirection int direction, int currentOverScroll, int totalOverScroll); /** * @param scrollDirection Direction of the overscroll: SCROLL_DIRECTION_UP, SCROLL_DIRECTION_DOWN */ public abstract void onDirectionNestedPreScroll(CoordinatorLayout coordinatorLayout, V child, View target, int dx, int dy, int[] consumed, @ScrollDirection int scrollDirection); @Override public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, V child, View directTargetChild, View target, int nestedScrollAxes) { return (nestedScrollAxes & View.SCROLL_AXIS_VERTICAL) != 0; } @Override public void onNestedScrollAccepted(CoordinatorLayout coordinatorLayout, V child, View directTargetChild, View target, int nestedScrollAxes) { super.onNestedScrollAccepted(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes); } @Override public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, V child, View target) { super.onStopNestedScroll(coordinatorLayout, child, target); } @Override public void onNestedScroll(CoordinatorLayout coordinatorLayout, V child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) { super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed); if (dyUnconsumed > 0 && mTotalDyUnconsumed < 0) { mTotalDyUnconsumed = 0; mOverScrollDirection = ScrollDirection.SCROLL_DIRECTION_UP; } else if (dyUnconsumed < 0 && mTotalDyUnconsumed > 0) { mTotalDyUnconsumed = 0; mOverScrollDirection = ScrollDirection.SCROLL_DIRECTION_DOWN; } mTotalDyUnconsumed += dyUnconsumed; onNestedVerticalOverScroll(coordinatorLayout, child, mOverScrollDirection, dyConsumed, mTotalDyUnconsumed); } @Override public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, V child, View target, int dx, int dy, int[] consumed) { super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed); if (dy > 0 && mTotalDy < 0) { mTotalDy = 0; mScrollDirection = ScrollDirection.SCROLL_DIRECTION_UP; } else if (dy < 0 && mTotalDy > 0) { mTotalDy = 0; mScrollDirection = ScrollDirection.SCROLL_DIRECTION_DOWN; } mTotalDy += dy; onDirectionNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, mScrollDirection); } @Override public boolean onNestedFling(CoordinatorLayout coordinatorLayout, V child, View target, float velocityX, float velocityY, boolean consumed) { super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed); mScrollDirection = velocityY > 0 ? ScrollDirection.SCROLL_DIRECTION_UP : ScrollDirection.SCROLL_DIRECTION_DOWN; return onNestedDirectionFling(coordinatorLayout, child, target, velocityX, velocityY, mScrollDirection); } protected abstract boolean onNestedDirectionFling(CoordinatorLayout coordinatorLayout, V child, View target, float velocityX, float velocityY, @ScrollDirection int scrollDirection); @Override public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, V child, View target, float velocityX, float velocityY) { return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY); } @Override public WindowInsetsCompat onApplyWindowInsets(CoordinatorLayout coordinatorLayout, V child, WindowInsetsCompat insets) { return super.onApplyWindowInsets(coordinatorLayout, child, insets); } @Override public Parcelable onSaveInstanceState(CoordinatorLayout parent, V child) { return super.onSaveInstanceState(parent, child); } } 

Toda esta respuesta vino de este tipo: https://medium.com/@nullthemall/bottom-navigation-behavior-388b9b206667#.potyetdkb

Todo el proyecto se encuentra aquí

  • Agregar el comportamiento de vista de desplazamiento de la barra de aplicaciones a varias vistas en CoordinatorLayout
  • Tablayout de la biblioteca de soporte de diseño de Android mediante el diseño de pestañas personalizadas, pero el diseño que envuelve las pestañas
  • ¿Cómo restablecer la posición de la barra de herramientas controlada por el CoordinatorLayout?
  • El estilo TabLayout no puede resolver @ dimen / tab_max_width después de pasar a Android Design Support v23
  • Cómo establecer el divisor entre tabuladores en TabLayout de la biblioteca de soporte de diseño?
  • EditText getHint () devuelve null al usar la biblioteca de soporte de diseño
  • Texto personalizado de BottomNavigationView support android
  • FloatingActionButton con SnackBar y CoordinatorLayout no funcionará con proguard
  • Icono y texto de la pestaña utilizando la biblioteca de soporte de diseño de android
  • Viewpager desborda la pantalla dentro del diseño del coordinador
  • Android: ¿Cómo trabajar con CoordinatorLayout y barra de navegación translúcida?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.