Cuando se cambia el fragmento con SwipeRefreshLayout durante la actualización, el fragmento se congela pero en realidad sigue funcionando

ACTUALIZACIÓN: pensé que funcionó correctamente. Pero después de algunos problemas de prueba todavía existe * sniff *

Luego hice una versión más simple para ver qué pasa exactamente y me di cuenta de que el fragmento refrescante que debería haberse desprendido todavía quedaba allí. O exactamente, la vista del viejo fragmento que dejó 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:

        

El fragmento ContentView que utilizo para rellenar @id/container se configura como:

    

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; 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 que se muestre al cambiar 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 todo funciona como siempre, excepto que no puedes verlo.

    Bueno … Después de algunas dificultades finalmente resolví este problema por mí mismo, de una manera difícil …

    Solo necesito agregar estos en onPause() :

     @Override public void onPause() { super.onPause(); ... if (mSwipeRefreshLayout!=null) { mSwipeRefreshLayout.setRefreshing(false); mSwipeRefreshLayout.destroyDrawingCache(); mSwipeRefreshLayout.clearAnimation(); } } 

    Este problema parece estar todavía ocurriendo en appcompat 22.1.1. Envolver el SwipeRefreshLayout dentro de FrameLayout me solucionó esto

          

    Además de la respuesta de @ zlm2012, noté que este problema se reprodujo en la Biblioteca de soporte 21.0.0, pero parece estar corregido en este momento en 21.0.3

    La solución funciona, pero creo que es mejor poner esas líneas en su propia función, como:

     public void terminateRefreshing() { mSwipeRefreshLayout.setRefreshing(false); mSwipeRefreshLayout.destroyDrawingCache(); mSwipeRefreshLayout.clearAnimation(); } 

    y llamar cuando se cambia el fragmento.

     Fragment prevFrag = fragmentManager.findFragmentById(drawerContainerId); if(prevFrag instanceof SwipeRefreshFragment) { ((SwipeRefreshFragment)prevFrag).terminateRefreshing(); } fragmentManager.beginTransaction().replace(drawerContainerId, fragment).commit(); 

    ¡Funciona! Solo elimine la transición de su reemplazo de fragmento, en mi caso eliminé lo siguiente de mi código:

     .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) 

    Set clickable="true" en el diseño principal superior … Puede resolver el problema.

    Por el momento, puedes 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 relaciona con la animación interna para asegurarse de que la animación de actualización no vuelva si la actualización de la red ya se ha completado.

    Finalice SwipeRefresh siempre que se haga clic en el elemento del menú de navegación. Funcionó.

     private void selectItem(int position) { mSwipeRefreshLayout.setRefreshing(false); /* Other part of the function */ }