ocultar - Android: CollapsingToolbarLayout y SwipeRefreshLayout se atascan
ocultar barra de estado android (5)
Uso CollapsingToolbarLayout, RecyclerView y SwipeRefreshLayout juntos:
Xml:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="@dimen/collapse_toolbar_height"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
android:fitsSystemWindows="true"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="@+id/toolbar_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax" />
<include
layout="@layout/activity_main_toolbar"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<cz.yetanotherview.webcamviewer.app.helper.EmptyRecyclerView
android:id="@+id/mainList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
</android.support.v4.widget.SwipeRefreshLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/floating_action_button"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end"
android:layout_margin="16dp"
app:fabSize="mini"
android:src="@drawable/ic_action_edit"
android:onClick="assignSelectedWebCamsToCategory"/>
<com.github.clans.fab.FloatingActionMenu
android:id="@+id/floating_action_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="bottom|end"
android:paddingRight="10dp"
android:paddingBottom="8dp"
android:paddingLeft="10dp"
fab:menu_shadowColor="#37000000"
fab:menu_colorNormal="#DA4336"
fab:menu_colorPressed="#E75043"
fab:menu_colorRipple="#99FFFFFF"
fab:menu_icon="@drawable/fab_add"
fab:menu_buttonSpacing="10dp"
fab:menu_labels_textColor="@color/very_dark_grey"
fab:menu_labels_textSize="14sp"
fab:menu_labels_colorNormal="@color/white"
fab:menu_labels_colorPressed="@color/next_grey"
fab:menu_labels_colorRipple="#99FFFFFF"
fab:menu_labels_margin="8dp"
fab:menu_backgroundColor="@color/black_transparent">
<com.github.clans.fab.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_action_content_import"
fab:fab_size="mini"
fab:fab_label="@string/pref_import_from_server"
fab:fab_colorNormal="@color/white"
app:fab_colorPressed="@color/next_grey"
app:fab_colorRipple="#99FFFFFF"
android:onClick="showSelectionDialog"/>
<com.github.clans.fab.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_action_content_manually"
fab:fab_size="mini"
fab:fab_label="@string/create_manually"
fab:fab_colorNormal="@color/white"
app:fab_colorPressed="@color/next_grey"
app:fab_colorRipple="#99FFFFFF"
android:onClick="showAddDialog"/>
<com.github.clans.fab.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_action_content_suggestion"
fab:fab_size="mini"
fab:fab_label="@string/submit_suggestion"
fab:fab_colorNormal="@color/white"
app:fab_colorPressed="@color/next_grey"
app:fab_colorRipple="#99FFFFFF"
android:onClick="showSuggestionDialog"/>
</com.github.clans.fab.FloatingActionMenu>
</android.support.design.widget.CoordinatorLayout>
<include
layout="@layout/activity_main_drawer"/>
</android.support.v4.widget.DrawerLayout>
Código:
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
swipeRefreshLayout.setOnRefreshListener(this);
¿Cómo permitir la acción de actualización de deslizamiento solo cuando el diseño de la barra de herramientas contraída está completamente expandido y la vista de desplazamiento (vista de reciclaje) en la parte superior ? El comportamiento similar como en la aplicación Google+ o Inbox.
Incorrecto:
Bueno:
Finalmente,
Descubrí que SwipeRefreshLayout funciona sin "hacks" de la biblioteca de soporte versión 23.1.1 .
Simplemente use en su diseño:
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
</android.support.v4.widget.SwipeRefreshLayout>
y en código:
SwipeRefreshLayout swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
swipeRefreshLayout.setColorSchemeResources(R.color.green, R.color.red, R.color.yellow);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
//Your refresh code here
}
});
Y no olvides usar:
swipeRefreshLayout.setRefreshing(false);
después de usar su lógica de código;)
La
respuesta anterior
es perfecta para
AppCompatActivity
pero si usa
Fragment
, el siguiente fragmento lo ayudará.
Simplemente ponga
NestedScrollView
en xml de
fragment
<android.support.v4.widget.NestedScrollView 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:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="fill_vertical"
android:clipToPadding="false"
android:isScrollContainer="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<!-- A RecyclerView with some commonly used attributes -->
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/album_timeline_swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/album_timeline_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true" />
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.v4.widget.NestedScrollView>
Si te entiendo correctamente, quieres comenzar a actualizar solo después de que la barra de herramientas se expanda, ¿verdad? Entonces, primero se debe abrir CollapsingToolbarLayout y luego comenzar a actualizar. Lo logré con el siguiente código:
<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/coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!--PUT HERE WHAT EVER YOU WANT TO COLLAPSE, A TOOLBAR, ETC...-->
</LinearLayout>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:fadeScrollbars="false"
android:scrollbars="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout>
Y luego, en su fragmento / actividad, haga que implemente AppBarLayout.OnOffsetChangedListener (ahora la actualización está habilitada cuando la barra de herramientas está completamente expandida):
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (collapsingToolbarLayout.getHeight() + verticalOffset < 2 * ViewCompat.getMinimumHeight(collapsingToolbarLayout)) {
swipeRefreshLayout.setEnabled(false);
} else {
swipeRefreshLayout.setEnabled(true);
}
}
Anule onPause () y onResume () como en la respuesta @blackcj:
@Override
public void onResume() {
super.onResume();
appBarLayout.addOnOffsetChangedListener(this);
}
@Override
public void onPause() {
super.onPause();
appBarLayout.removeOnOffsetChangedListener(this);
}
Luego configure LinearLayoutManager en su reciclador Vista:
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
Para mí, esto funcionó de maravilla, primero appBarlayout se expande y solo luego swipeRefreshLayout desencadena la actualización.
Tuve que hacer que RecyclerView fuera el elemento principal de SwipeRefreshLayout para eliminar el problema usando Support Library 23.2.0. No se pudo solucionar teniendo un diseño de inclusión dentro de SwipeRefreshLayout
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/my_swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--<include layout="@layout/my_RecyclerView_layout"/> issue for me here -->
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
Actualización: este problema se ha resuelto en la última versión de la biblioteca de soporte (23.1.1+). Si está utilizando una versión anterior de la biblioteca de soporte, actualice o continúe leyendo.
Si está utilizando una versión anterior de la biblioteca de soporte, agregue un oyente de cambio de desplazamiento a su AppBarLayout para habilitar o deshabilitar su deslizamiento para actualizar el diseño en consecuencia. Código adicional disponible aquí:
https://gist.github.com/blackcj/001a90c7775765ad5212
Cambios relevantes:
public class MainActivity extends AppCompatActivity implements AppBarLayout.OnOffsetChangedListener {
...
private AppBarLayout appBarLayout;
private SwipeRefreshLayout mSwipeRefreshLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.contentView);
appBarLayout = (AppBarLayout) findViewById(R.id.appBarLayout);
}
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
//The Refresh must be only active when the offset is zero :
mSwipeRefreshLayout.setEnabled(i == 0);
}
@Override
protected void onResume() {
super.onResume();
appBarLayout.addOnOffsetChangedListener(this);
}
@Override
protected void onPause() {
super.onPause();
appBarLayout.removeOnOffsetChangedListener(this);
}
}