android - setcolorschemecolors - Cuando se cambia el fragmento con SwipeRefreshLayout durante la actualización, el fragmento se congela pero aún funciona
swiperefreshlayout recyclerview (8)
ACTUALIZACIÓN: pensé que funcionaba correctamente. Pero después de algunos problemas de prueba todavía existe * sniff *
Luego hice una versión más simple para ver qué sucedía exactamente y llegué a saber que el fragmento refrescante que debería haberse separado todavía quedaba allí. O exactamente, la vista del fragmento antiguo que queda allí, encima del fragmento más nuevo. Como el fondo de RecyclerView de mi aplicación original no es transparente, resultó lo que dije antes.
FIN DE ACTUALIZACIÓN
Tengo una
MainActivity
con un diseño como este:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer_layout"
android:layout_width="match_parent" android:layout_height="match_parent">
<!-- As the main content view, the view below consumes the entire
space available using match_parent in both dimensions. -->
<FrameLayout android:id="@+id/container" android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- android:layout_gravity="start" tells DrawerLayout to treat
this as a sliding drawer on the left side for left-to-right
languages and on the right side for right-to-left languages.
If you''re not building against API 17 or higher, use
android:layout_gravity="left" instead. -->
<!-- The drawer is given a fixed width in dp and extends the full height of
the container. -->
<fragment android:id="@+id/navigation_drawer"
android:layout_width="@dimen/navigation_drawer_width" android:layout_height="match_parent"
android:layout_gravity="start" tools:layout="@layout/fragment_navigation_drawer" />
</android.support.v4.widget.DrawerLayout>
El fragmento
ContentView
que uso para llenar
@id/container
está configurado como:
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/contentView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/tweet_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/grey_300"/>
</android.support.v4.widget.SwipeRefreshLayout>
Y aquí está
onCreateView()
de
ContentView
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View inflatedView = inflater.inflate(R.layout.fragment_content, container, false);
mRecyclerView = (RecyclerView) inflatedView.findViewById(R.id.tweet_list);
mRecyclerView.setHasFixedSize(false);
mLinearLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
mRecyclerView.setLayoutManager(mLinearLayoutManager);
mTweetList = new ArrayList<Tweet>;
mAdapter = new TweetAdapter(mTweetList);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mSwipeRefreshLayout = (SwipeRefreshLayout) inflatedView.findViewById(R.id.contentView);
mSwipeRefreshLayout.setOnRefreshListener(
...
);
return inflatedView;
}
Luego, en
MainActivity
, cambio el contenido para mostrar cambiando diferentes
ContentView
.
Todo se ve bien, excepto una cosa: cuando cambio
ContentView
fragmentos de
ContentView
DURANTE la actualización por el cajón de navegación, el contenido se congela.
Pero en realidad todas las cosas funcionan como de costumbre, excepto que no puedes verlo.
¡Funciona! Simplemente elimine la transición de su reemplazo de fragmentos, en mi caso eliminé lo siguiente de mi código:
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
Además de la respuesta @ zlm2012, noté que este problema se reprodujo en Support Library 21.0.0, pero parece estar solucionado ahora en 21.0.3
Bueno ... Después de algunas dificultades, finalmente resolví este problema por mí mismo, de una manera complicada ...
Solo necesito agregar estos en
onPause()
:
@Override
public void onPause() {
super.onPause();
...
if (mSwipeRefreshLayout!=null) {
mSwipeRefreshLayout.setRefreshing(false);
mSwipeRefreshLayout.destroyDrawingCache();
mSwipeRefreshLayout.clearAnimation();
}
}
Establezca
clickable="true"
en el diseño principal superior ... Puede resolver el problema.
Este problema parece seguir ocurriendo en appcompat 22.1.1. Envolviendo el SwipeRefreshLayout dentro de un FrameLayout me resolvió esto
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/contentView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/tweet_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/grey_300" />
</android.support.v4.widget.SwipeRefreshLayout>
</FrameLayout>
La solución funciona, pero creo que es mejor simplemente poner esas líneas en su propia función, como:
public void terminateRefreshing() {
mSwipeRefreshLayout.setRefreshing(false);
mSwipeRefreshLayout.destroyDrawingCache();
mSwipeRefreshLayout.clearAnimation();
}
y llame al cambiar el fragmento.
Fragment prevFrag = fragmentManager.findFragmentById(drawerContainerId);
if(prevFrag instanceof SwipeRefreshFragment) {
((SwipeRefreshFragment)prevFrag).terminateRefreshing();
}
fragmentManager.beginTransaction().replace(drawerContainerId, fragment).commit();
Por el momento, puede evitar el problema al:
public class FixedRefreshLayout extends SwipeRefreshLayout {
private static final String TAG = "RefreshTag";
private boolean selfCancelled = false;
public FixedRefreshLayout(Context context) {
super(context);
}
public FixedRefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected Parcelable onSaveInstanceState()
{
if(isRefreshing()) {
clearAnimation();
setRefreshing(false);
selfCancelled = true;
Log.d(TAG, "For hide refreshing");
}
return super.onSaveInstanceState();
}
@Override
public void setRefreshing(boolean refreshing) {
super.setRefreshing(refreshing);
selfCancelled = false;
}
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
if(hasWindowFocus && selfCancelled) {
setRefreshing(true);
Log.d(TAG, "Force show refreshing");
}
}
}
Esto tiene la ventaja adicional de reanudar la animación en caso de que decida no cambiar el fragmento (proveniente de algún menú). También se vincula con la animación interna para asegurarse de que la animación de actualización no regrese si la actualización de la red ya se ha completado.
Termine SwipeRefresh cada vez que se hace clic en el elemento del menú de navegación. Funcionó.
private void selectItem(int position) {
mSwipeRefreshLayout.setRefreshing(false);
/*
Other part of the function
*/
}