android android-listview scroll android-actionbar vertical-scrolling

android - Ocultando ActionBar en RecyclerView/ListView onScroll



collapsingtoolbarlayout scroll flags (7)

En mi aplicación obtuve una actividad con algún tipo de barra de acciones en la parte superior y la vista de lista debajo. Lo que quiero hacer es desplazarlo hacia ARRIBA con la lista, de modo que se oculta y luego, cuando la lista se está desplazando hacia abajo, debería desplazarse hacia abajo con la lista, como si estuviera justo sobre el borde superior de la pantalla. ¿Cómo puedo lograr esta funcionalidad?


Actualizado el 3/06/2015:

Google ahora admite esto usando CoordinatorLayout .

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/main_content" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:id="@+id/appbar" 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:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:layout_scrollFlags="scroll|enterAlways" /> <android.support.design.widget.TabLayout android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="wrap_content" /> </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end|bottom" android:layout_margin="@dimen/fab_margin" android:src="@drawable/ic_done" /> </android.support.design.widget.CoordinatorLayout>

Fuente: https://github.com/chrisbanes/cheesesquare/blob/master/app/src/main/res/layout/include_list_viewpager.xml

Documentado aquí: https://developer.android.com/reference/android/support/design/widget/AppBarLayout.html

Respuesta Original:

Ejemplo similar a las aplicaciones de Google Play Music y Umano:

https://github.com/umano/AndroidSlidingUpPanel

Eche un vistazo al código en este repositorio. A medida que desliza el panel hacia arriba, la Barra de acciones también se desliza hacia arriba.

De la demostración :

getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY); SlidingUpPanelLayout layout = (SlidingUpPanelLayout) findViewById(R.id.sliding_layout); layout.setShadowDrawable(getResources().getDrawable(R.drawable.above_shadow)); layout.setAnchorPoint(0.3f); layout.setPanelSlideListener(new PanelSlideListener() { @Override public void onPanelSlide(View panel, float slideOffset) { Log.i(TAG, "onPanelSlide, offset " + slideOffset); if (slideOffset < 0.2) { if (getActionBar().isShowing()) { getActionBar().hide(); } } else { if (!getActionBar().isShowing()) { getActionBar().show(); } } } @Override public void onPanelExpanded(View panel) { Log.i(TAG, "onPanelExpanded"); } @Override public void onPanelCollapsed(View panel) { Log.i(TAG, "onPanelCollapsed"); } @Override public void onPanelAnchored(View panel) { Log.i(TAG, "onPanelAnchored"); } });

Descargue el ejemplo aquí:

https://play.google.com/store/apps/details?id=com.sothree.umano

ListView - sin bibliotecas:

Hace poco quería la misma funcionalidad y esto funciona perfectamente para mí:

A medida que el usuario se desplaza hacia arriba, la barra de acciones se ocultará para darle al usuario toda la pantalla para trabajar con ella.

A medida que el usuario se desplaza hacia abajo y suelta, la ActionBar volverá.

getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY); listView.setOnScrollListener(new OnScrollListener() { int mLastFirstVisibleItem = 0; @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (view.getId() == listView.getId()) { final int currentFirstVisibleItem = listView.getFirstVisiblePosition(); if (currentFirstVisibleItem > mLastFirstVisibleItem) { // getSherlockActivity().getSupportActionBar().hide(); getSupportActionBar().hide(); } else if (currentFirstVisibleItem < mLastFirstVisibleItem) { // getSherlockActivity().getSupportActionBar().show(); getSupportActionBar().show(); } mLastFirstVisibleItem = currentFirstVisibleItem; } } });

RecyclerView - sin bibliotecas

this.mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { int mLastFirstVisibleItem = 0; @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); final int currentFirstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition(); if (currentFirstVisibleItem > this.mLastFirstVisibleItem) { MainActivity.this.getSupportActionBar().hide(); } else if (currentFirstVisibleItem < this.mLastFirstVisibleItem) { MainActivity.this.getSupportActionBar().show(); } this.mLastFirstVisibleItem = currentFirstVisibleItem; } });

¡Avíseme si necesita más ayuda!


Creo que va a funcionar bien .....

listView.setOnScrollListener(new OnScrollListener() { int mLastFirstVisibleItem = listView.getLastVisiblePosition(); boolean isScrolling = false; @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if(scrollState == 0) isScrolling = false; else if(scrollState == 1) isScrolling = true; else if(scrollState == 2) isScrolling = true; } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (view.getId() == myTeamListView.getId()) { if(isScrolling) { final int currentFirstVisibleItem = myTeamListView.getLastVisiblePosition(); if (currentFirstVisibleItem > mLastFirstVisibleItem) { ((AppCompatActivity)getActivity()).getSupportActionBar().hide(); } else if (currentFirstVisibleItem < mLastFirstVisibleItem) { ((AppCompatActivity)getActivity()).getSupportActionBar().show(); } mLastFirstVisibleItem = currentFirstVisibleItem; } } } });


Estoy seguro de que no es la mejor solución. Pero aún no he encontrado uno mejor. Espero que sea útil.

static boolean scroll_down; ... mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (scroll_down) { actionBar.hide(); } else { actionBar.show(); } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); if (dy > 70) { //scroll down scroll_down = true; } else if (dy < -5) { //scroll up scroll_down = false; } } });


Experimenta el parpadeo ya que al ocultar / mostrar la barra de acciones, se muestra el espacio disponible para los cambios en el diseño del contenido, lo que provoca una retransmisión. Con esto, también cambia el índice de la posición del primer elemento visible (puede verificarlo al cerrar sesión mLastFirstVisibleItem y currentFirstVisibleItem .

Puede hacer frente al parpadeo dejando que ActionBar superponga su diseño de contenido. Para habilitar el modo de superposición para la barra de acciones, debe crear un tema personalizado que amplíe un tema existente de la barra de acciones y establezca la propiedad android: windowActionBarOverlay en verdadero .

Con esto puedes eliminar el parpadeo pero la barra de acción superpondrá el contenido de tu lista. Una solución fácil para esto es establecer el relleno superior de listview (o el diseño raíz) a la altura de la barra de acción.

<ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingTop="?android:attr/actionBarSize" />

Desafortunadamente, esto dará como resultado un relleno constante en la parte superior. Un refinamiento de esta solución es agregar una vista de encabezado a la vista de lista que tiene la altura de ? Android: attr / actionBarSize (y eliminar el conjunto de relleno superior anteriormente)


Lo que está buscando se llama patrón de retorno rápido , aplicado a la barra de acción. La aplicación Google IO 2014 usa exactamente eso. Lo uso en una de mis aplicaciones, puede verificar el código fuente de esa aplicación de Google para ver cómo lo obtuvieron. La clase BaseActivity es donde tienes lo que necesitas, lee el código y extrae solo esa funcionalidad específica. ¡Disfruta la codificación! :)


Si está utilizando un CoordinatorLayout, este es el truco.

<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" />

La app:layout_scrollFlags="scroll|enterAlways" hará que nuestra barra de herramientas se desplace fuera de la pantalla cuando el usuario se desplace por la lista y tan pronto como comience a desplazarse, la barra de herramientas volverá a aparecer.


Tengo un pensamiento que es una buena idea.

listView.setOnScrollListener(new OnScrollListener() { int mLastFirstVisibleItem = 0; @Override public void onScrollStateChanged(AbsListView view, int scrollState) { switch (scrollState) { case OnScrollListener.SCROLL_STATE_FLING: if (view.getId()==lv_searchresult_results.getId()){ final int currentFirstVisibleItem=lv_searchresult_results.getFirstVisiblePosition(); if(currentFirstVisibleItem>mLastFirstVisibleItem){ ObjectAnimator.ofFloat(toolbar, "translationY", -toolbar.getHeight()).start(); else if(currentFirstVisibleItem<(mLastFirstVisibleItem)){ ObjectAnimator.ofFloat(toolbar, "translationY", 0).start(); } mLastFirstVisibleItem= currentFirstVisibleItem; } if(lv_searchresult_results.getLastVisiblePosition() == myAdapter.getListMap().size()){ if(myAdapter.getListMap().size() < allRows&&!upLoading){ } } break; case OnScrollListener.SCROLL_STATE_IDLE: if (view.getFirstVisiblePosition()<=1){ ObjectAnimator.ofFloat(toolbar, "translationY", 0).start(); } if(lv_searchresult_results.getLastVisiblePosition() == myAdapter.getListMap().size()){ if(myAdapter.getListMap().size() < allRows&&!upLoading){ } } break;