ACTUALIZACIÓN: pensé que funcionaba correctamente. Pero después de algunas pruebas problema todavía existe *sniff*

Luego me hizo una versión más simple para ver qué es exactamente lo que sucederá y puedo llegar a saber que la refrescante fragmento que debería haber sido separado todavía a la izquierda. O exactamente, la vista de la antigua fragmento de la izquierda, en la parte superior de la más reciente fragmento. Desde RecyclerView del fondo de mi aplicación original no es transparente, por lo que resultó lo que he dicho antes.

FINAL DE LA ACTUALIZACIÓN DE


Tengo un 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 puedo usar 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í es 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;
}

A continuación, en MainActivity me cambie el contenido para mostrar por conmutación de diferentes ContentView. Todo se ve bien, excepto una cosa: cuando me cambie ContentView fragmentos DURANTE refrescante por la navegación cajón, entonces el contenido de la congela. Pero, en realidad, todas las cosas funcionan como de costumbre, excepto que usted no puede ver.

  • Normal, que quieres actualizar, &, mientras que el cambio de toda la lista, entonces cuando la actualización de terminar, no intente volver a cargar datos de que había cambiado. Usted debe bloquear el pase cuando refrescante.
  • Bien, parece que Google no falla… Después de actualizar a AppCompat v21.0.2, todo el dolor se ha ido XD. De todas maneras gracias <3
InformationsquelleAutor zlm2012 | 2014-11-21

8 Comentarios

  1. 104

    Bueno… Después de algunas dificultades finalmente he resuelto este problema por mí mismo, en un complicado camino…

    Sólo tengo que añadir que estas en onPause() :

    @Override
    public void onPause() {
        super.onPause();
        ...
    
        if (mSwipeRefreshLayout!=null) {
            mSwipeRefreshLayout.setRefreshing(false);
            mSwipeRefreshLayout.destroyDrawingCache();
            mSwipeRefreshLayout.clearAnimation();
        }
    }
    • Aunque he de añadir este código pero parece que no funciona,mi apoyo de la biblioteca es 22.0.0,de hecho me parece que la congelación no desaparece en mi aplicación,trato de usar setTransition() y esto también puede sovle el problema ,pero tanto en este código y setTransition() no son completamente cierto,si va a reemplazar el fragmento dentro de aproximadamente un segundo cuando pase el dedo de diseño comienza refrescante también encontrará congelación de contenido,pero una vez que excedan de un corto tiempo el reemplazo de un fragmento funciona correctamente,mi última solución es deformar el pase de diseño en un framelayout,y no es necesario agregar otro código más.
    • El problema todavía persiste con support-v4:22.1.1 , he tenido este problema, mientras que el uso de deslizar para actualizar y menú de deslizamiento. Traté de setRefreshing falso mientras llamaba fragmento de la transacción, pero que no trabajo. Gracias por la solución.
    • Aunque esto puede parecer para solucionar el problema, se ralentiza todo. Si yo destruir el dibujo de memoria caché y borrar la animación de la capa de la swipeRefreshLayout, hay un retraso(claramente visible para el ojo humano) cuando se cambia de 1 fragmento a otro. Google, va a arreglar esto?
    • Esto no funciona en appcompat-v7:22.2.0
    • Envolver el SwipeRefreshLayout dentro de un FrameLayout resuelto en appcompat v7:22+
    • Usted es un buen hombre. Funciona perfecto para mí con appcompat-v7:22.2.0
    • Esta solución funciona muy bien para mí.Gracias por que.
    • Gracias esto me funciona, estoy usando la app de appcompat-v7:22.2.1
    • Funciona aquí también: com.android.support:appcompat-v7:24.2.1
    • Gracias. Yo sólo tenía setRefreshing(false) durante FragmentTransaction. Después de la adición de clearAnimation(), mi aplicación funciona sin congelar.
    • Para mí, este enfoque requiere el uso de SwipeRefreshLayout.removeAllViews();
    • Usted salvar mi vida!

  2. 75

    Este problema parece estar ocurriendo en appcompat 22.1.1. Envolver el SwipeRefreshLayout dentro de un FrameLayout resuelto este para mí

    <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>
    • Funciona muy bien, gracias! Menos chapucero, aunque tal vez un poco más ineficiente que el más votado de la solución?
    • Hola @Pin, yo no creo que sea una solución más pesado que el otro.. FrameLayout es el más ligero ViewGroup elemento, no debe agregar tanta complejidad.
    • Esto funciona. Cualquier idea sobre el ¿por qué?
    • Gracias! ayudó a
    • esto no funcionó en mi caso
    • Esto funciona también para appcompat-v7:23.3.0
    • Después de cambiar la ficha, en la SwipeRefreshLayout se ha ido. Me fui con zlm2012 ‘s solución.
    • gracias! resuelto el problema en appcompat-v7:25.0.1 demasiado
    • Esta realidad trabajaba para mí, mientras que en un Fragmento. Wow.
    • Gracias! Es resolver mi problema! He perdido una gran cantidad de tiempo en la búsqueda de la razón y de la solución. Se debe ser aceptado como respuesta correcta!
    • En 25.2.0 error persiste y este problema resuelto. Yo quería voltear la mesa antes de encontrar esta solución. Gracias.
    • Esta es la solución de trabajo para appcompat-v7:24+.. yo creo que esto debe ser aceptado respuesta… Gracias @user1354603

  3. 3

    Además a @zlm2012 respuesta, me di cuenta de que este problema fue reproducido en la Biblioteca de Soporte 21.0.0, pero parece ser fija ahora en 21.0.3

    • En 22.2.1 error persiste.
    • Me encontré con este error con compile 'com.android.support:appcompat-v7:25.1.0'
  4. 1

    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 llame al cambiar el fragmento.

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

    Funciona! Sólo hay que quitar la transición de su fragmento de reemplazo, en mi caso he quitado el siguiente de mi código:

    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
  6. 1

    Conjunto clickable="true" en la parte superior de los padres de diseño… puede resolver el problema.

    • esta solución funciona para el evento click , pero para la navegación cajón pase caso de que esta solución no funciona.
  7. 0

    Por el momento, puede evitar el problema:

    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 añadida de la reanudación de la animación en caso de que decida no cambiar el fragmento (procedentes de algunas de menú). También se vincula con el interior de animación para asegurarse de que el frescor de la animación no retorno si la red de actualización ya se ha completado.

  8. 0

    Terminar SwipeRefresh siempre de navegación elemento de menú se hace clic.
    Se trabajó.

    private void selectItem(int position) {
    
           mSwipeRefreshLayout.setRefreshing(false);
    
           /*
            Other part of the function
           */
    }
    • Yo hice esto, pero yo también tenía que hacer lo que el aceptado la respuesta, dijo, de lo contrario, yo tengo un montón de puntos de vista sobre la pantalla a la izquierda encima de partida para actualizar

Dejar respuesta

Please enter your comment!
Please enter your name here