He implementado SwipeRefreshLayout en mi aplicación, pero sólo puede tener una directa hijo que debe ser el listview. Estoy tratando de averiguar cómo agregar un vacío textview para el siguiente trabajo de archivo XML:

<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipe_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ListView
        android:id="@+id/listViewConversation"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:dividerHeight="1dp" />

</android.support.v4.widget.SwipeRefreshLayout>

Envolviendo en un Lineal/Relative layout hace buggy porque el listview siempre actualizará cuando se quiere se deslice hacia atrás hasta el listview. Una manera que se me ocurre es hacerlo mediante programación, pero supongo que no es la mejor opción.

Usted puede aprender cómo implementar el uso de este tutorial: Desliza el dedo a la actualización de la GUÍA de

Así que, básicamente, funciona todo bien, pero me gustaría añadir una vista vacía que muestra un mensaje cuando el listview está vacía.

  • Trate de usar un FrameLayout.
InformationsquelleAutor Niels | 2014-04-09

15 Comentarios

  1. 52

    No me gustó la limitación a un solo niño.
    Además, la implementación actual de la SwipeRefreshLayout tiene un codificado de la «magia» de manejo para el ScrollView, ListView y GridView que activan sólo si la vista es el directo de el niño de su propio punto de vista.

    Que dijo que la buena noticia es que es de código abierto, así que usted puede copiar el código y adaptarse a sus necesidades o usted puede hacer lo que yo hice:

    El uso de dos DIFERENTES SwipeRefreshLayout, uno para la vista Vacía y uno para el ListView.

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.tobrun.example.swipetorefresh.MainActivity">
    
        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swipeRefreshLayout_listView"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <ListView
                android:id="@+id/listView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
    
        </android.support.v4.widget.SwipeRefreshLayout>
    
        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swipeRefreshLayout_emptyView"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <ScrollView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fillViewport="true">
    
                <TextView
                    android:id="@+id/emptyView"
                    android:text="@string/empty"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:gravity="center" />
    
            </ScrollView>
    
        </android.support.v4.widget.SwipeRefreshLayout>
    
    
    </FrameLayout>

    A continuación, dígale a su listview que el vacío de la vista de lista es el pase de actualización de diseño de la vista vacía.

    Ahora el vacío de actualización de diseño se oculta automáticamente por la vista de lista cuando se disponen de datos y se muestra cuando la lista está vacía.

    El pase de actualización de diseño de la lista no debería recibir eventos de toque causar la lista está oculto.

    Buena suerte.

    • He aquí algunos ejemplo de código: github.com/AndroidExamples/SwipeRefreshLayout-ListViewExample
    • La solución que funcionó muy bien (a diferencia de todos los otros sugirió queridos(, pero tuve que siga exactamente su diseño (envolver el pase diseños relativo en el diseño). Gracias!
    • eres bienvenido. Que la implementación de referencia que no es mía, me la acaba de encontrar, y la pereza me vinculados que en lugar de proporcionar la mía propia. No hay necesidad de utilizar un pariente de diseño, puede utilizar un marco de diseño o de otros planos. Lo importante es que el SwipeRefreshLayout actuar sobre su hijo único, lo que significa que usted necesita 2: uno para el listview, uno para la vista vacía. FrameLayout son más eficientes en las actuaciones si usted puede hacer uso de ellos.
    • Esto funcionó bien, gracias! También es de destacar que el contenido de la scrollview puede ser cualquier cosa, no sólo de un textview. Bueno si quieres una mejor vista vacía con un icono o algo más, por ejemplo.
    • ¿Puedo hacerle una pregunta tonta aquí: ¿por Qué el scrollview hará el emptyview del SwipeRefreshLayout trabajo, mientras que sin ella no?
    • ¿qué se entiende por «trabajo»? Tu pregunta no tiene sentido. Usted probablemente significaba *listview en lugar de scrollview. Si ese es el caso me puede responder: Cuando se establece una vista vacía para el control listview ocultarse automáticamente / mostrar (setVisibility VISIBLE / IDO) el emptyview (y viceversa) cuando tiene cero elementos. Si la vista vacía es un golpe que se hacen visibles en el diseño y por lo tanto reaccionan al tacto
    • Lo siento, tropezando aquí de nuevo, no entendía su pregunta antes. La razón es que SwipeRefreshLayout permitir que tire para actualizar sólo si contiene algo quiere desplazarse (como un ScrollView, un ListView o un RecyclerView).
    • No hay necesidad de crear otro <android.apoyo.v4.widget.SwipeRefreshLayout …>. ver mi limpio solución.
    • Yo no lo llamaría reemplazar el listview para cambiar el comportamiento de setVisibility limpieza. Lo sentimos, pero el real limpio solución es utilizar un NestedScrollview. Simplemente no existía cuando escribí esta respuesta. Y mi respuesta es aún más limpio, a continuación, la suya. 🙂
    • oh.. yo si se de que otra respuesta. Vi el tuyo. Está bien.. ListView es obsoleta de todos modos.
    • funciona con RecyclerView así
    • cómo va a trabajar para recylerview
    • Exactamente el mismo

  2. 31

    No hay necesidad para cualquier solución.

    Usted puede simplemente utilizar este punto de vista de la jerarquía :

        <FrameLayout ...>
    
            <android.support.v4.widget.SwipeRefreshLayout ...>
    
                <ListView
                    android:id="@android:id/list" ... />
            </android.support.v4.widget.SwipeRefreshLayout>
    
            <TextView
                android:id="@android:id/empty" ...
                android:text="@string/empty_list"/>
        </FrameLayout>

    A continuación, en el código, simplemente llame a:

    _listView.setEmptyView(findViewById(android.R.id.empty));

    Que es.


    EDIT: Si usted desea ser capaz de deslizar para actualizar incluso cuando el vacío se muestra, usted tendrá que evitar de alguna manera ocultar el ListView, así que usted podría utilizar un ListView personalizado que tiene esta función en el interior:

    @Override
      public void setVisibility(final int visibility)
        {
        if(visibility!=View.GONE||getCount()!=0)
          super.setVisibility(visibility);
        }

    Junto con la solución que me escribió, el pase a la actualización de muestra, no importa cuántos artículos que usted está mostrando.

    Por supuesto, si usted realmente quiere ocultar el ListView, usted debe cambiar el código. Tal vez agregar «setVisibilityForReal(…)» 🙂

    • No es obvio que usted necesita para cambiar a un FrameLayout o RelativeLayout si se utiliza un LinearLayout antes de agregar el SwipeRefreshLayout. Una combinación de este y el comentario de arriba sobre el uso de un segundo SwipeRefreshLayout trabajo (si usted necesita el vacío de la lista para actualizar así).
    • Yo no lo entiendo. no lo escribí trabajo para usted?
    • Pero yo no pase el dedo hacia abajo esta vacía de la vista a que se actualice. Puedo obtener la solución para esto.. Gracias de antemano. @androiddeveloper
    • Creo que algo de lo que escribió se borró. ¿Quiere usted decir que con una vista vacía, no se puede hacer deslizar el dedo-to-refresh?
    • Me desplaza hacia abajo (no llegó a la cima) y se desplaza hacia arriba de la página, empieza a refrescar. No entiendo el comportamiento.. @androiddeveloper
    • No se tiene la capacidad para actualizar la lista de nuevo después de la implementación de esta solución
    • Por favor explique. Puedo usar esta solución en mi propia aplicación(aquí: play.google.com/store/apps/details?id=com.lb.app_manager ), y no tengo problemas con el listView en todos los
    • Lo siento decir pero después de usar la solución, cuando los datos no está en la lista, soy incapaz de pasar y se actualiza de nuevo. mi aplicación es igual a la tuya
    • Si lo desea, puede crear una nueva pregunta aquí, con lo que es relevante (XML y el código, pero no demasiado), y me dejó saber acerca de ella. Tal vez podría ayudar.
    • Por favor, ayúdame aquí stackoverflow.com/questions/30818097/…
    • Si quieres ser capaz de tirar de la actualización de la vista vacía tendrás que poner el FrameLayout (que incluye la ListView y la EmptyView) dentro de la SwipeRefreshLayout. Además, el conjunto android:clickable=”true” en el FrameLayout
    • Asombrados al ver soo muchas upvotes. La solución anterior no funciona cuando listview está vacía yo.e vista Vacía está mostrando.
    • Esto es por diseño, no tiene sentido para desplazarse de un punto de vista que no es desplazable (textview en este caso), así que pase a la actualización no funciona. Trate de usar la solución «antoinem», sugirió. También, si lo desea, creo que se puede utilizar un encabezado en el ListView, que sustituirá a la vista vacía he mostrado, y usted será responsable de mostrar o no (en función de si la lista está vacía o no), mediante el establecimiento de su visibilidad.
    • Con el debido respeto que tiene sentido cuando los datos no se puede cargar debido a que no hay internet o servidor estaba abajo. Tan vacía de la vista puede ser renovado. Muchas gracias por mencionar a @antoinem solución. Anteriormente hice tratado de la misma, pero android:clickable=true fue la clave y lo hizo trabajado. Todavía esto no funciona con el estándar de SwipeRefreshLayout! Tiene el uso de github.com/googlesamples/android-SwipeRefreshMultipleViews
    • Bien, esto no toma mucho esfuerzo. Sólo puede evitar hacer el ListView invisible, mediante la ampliación de la misma. He añadido una actualización, y también he comprobado. Funciona bien, incluso si no hay elementos en la lista.
    • ampliación de ListView y evitar la invisibilidad suena lógico. Le dará una oportunidad la próxima vez. Gracias.
    • Ordenar y dulce Solución…

  3. 11

    Realidad, lo único que le falta es tener que vaciar TextView ser envuelto con un desplazable contenedor – por ejemplo ScrollView. Para más detalles, echa un vistazo a SwipeRefreshLayout.canChildScrollUp() método y su uso.

    De todos modos, volviendo al punto. Aquí es un éxito de la aplicación:

    activity_some.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/swipe_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:measureAllChildren="true">
    
            <WebView
                android:id="@+id/webview"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
    
            <include layout="@layout/empty" />
    
        </FrameLayout>
    
    </android.support.v4.widget.SwipeRefreshLayout>

    Donde su empty.xml es, básicamente, cualquier cosa que usted desea que se envuelve con una ScrollView.

    empty.xml

    <?xml version="1.0" encoding="utf-8"?>
    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">
    
        <TextView
            android:text="Nothing here..."
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    
    </ScrollView>

    Ahora en el fin de deshacerse de la famosa SwipeRefreshLayout actualizar-sólo-cuando-en-el-top problema, cambie el SwipeRefreshLayout cuando sea necesario (Fragmento específico):

    private ViewTreeObserver.OnScrollChangedListener mOnScrollChangedListener;
    
    @Override
    public void onStart() {
        super.onStart();
    
        mOnScrollChangedListener = new ViewTreeObserver.OnScrollChangedListener() {
            @Override
            public void onScrollChanged() {
                int scrollY = mWebView.getScrollY();
                if (scrollY == 0)
                    swipeLayout.setEnabled(true);
                else
                    swipeLayout.setEnabled(false);
    
            }
        };
        swipeLayout.getViewTreeObserver().addOnScrollChangedListener(mOnScrollChangedListener);
    }
    
    @Override
    public void onStop() {
        swipeLayout.getViewTreeObserver().removeOnScrollChangedListener(mOnScrollChangedListener);
        super.onStop();
    }

    Que es! Espero que ayude! 😉

    Por cierto, ¿por qué usar la SwipeRefreshLayout con FrameLayout de esta manera? Porque de esta manera usted puede hacer suaves animaciones de transición, como fundido efectos, y cualquiera de sus estado puntos de vista pueden ser swipeable (en caso de que desee un sistema unificado fetch/actualizar/reintentar mecanismo).

    • Gracias, yo he terminado de utilizar la solución. Voy a añadir un poco de observación, sin embargo: la clave es que el ScrollView tiene que ser un hijo de SwipeRefreshLayout. En mi caso, he inicialmente trató sólo para envolver la vista vacía (que era una especie de hermano para el SwipeRefreshLayout) en un ScrollView, que no era suficiente.
    • Te mereces más upvotes. Vale la pena mencionar, a todos, no olvides usar android:fillViewport="true" en el ScrollView
  4. 8

    Esto es lo que hice :
    He desactivado el deslizar para actualizar, a menos que mi listView es de hasta.

    mBookedProductsListView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView absListView, int i) {
            }
            @Override
            public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount,     int totalItemCount) {
                if (firstVisibleItem == 0)
                    mSwipeRefreshLayout.setEnabled(true);
                else
                    mSwipeRefreshLayout.setEnabled(false);
            }
        });

    Mi Xml :

    <?xml version="1.0" encoding="utf-8"?>
    
    <android.support.v4.widget.SwipeRefreshLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/swipeRefreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
    
    <RelativeLayout
            android:id="@+id/productListLL"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            >
    
        <EditText
                android:id="@+id/search"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_alignParentTop="true"
                android:background="#a4aeb8"
                android:drawableRight="@drawable/search_icon"
                android:paddingRight="15dp"
                android:textColor="@android:color/white"
                android:paddingLeft="15dp"
                android:hint="Rechercher"
                android:textColorHint="@android:color/white"
                android:inputType="textCapWords|textNoSuggestions"
                />
    
        <include android:layout_width="match_parent" android:layout_height="wrap_content" layout="@layout/filter_by_categories_buttons" android:id="@+id/categoriesTree" android:layout_below="@id/search" />
    
        <ListView
                android:id="@+id/productListLV"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:divider="@drawable/product_listview_divider"
                android:dividerHeight="1dp"
                android:scrollbars="none"
                android:overScrollMode="never"
                android:choiceMode="multipleChoiceModal"
                android:background="#e7eaef"
                android:visibility="gone"
                android:layout_below="@id/categoriesTree"
                />
    
    </RelativeLayout>
    
    </android.support.v4.widget.SwipeRefreshLayout>

    Funciona como un encanto.

  5. 6

    He encontrado con el mismo problema. Es molesto que SwipeRefreshLayout sólo puede tener un AdpaterView niño.

    Si una vista vacía se establece para un AdpaterView, se establecerá como oculto si no se dispone de datos. Sin embargo, SwipeRefreshLayout necesidades de un AdpaterView a trabajar. Así, extiendo AdpaterView para hacerlo todavía se muestra, incluso si está vacío.

    @Override
    public void setVisibility(int visibility) {
        if (visibility == View.GONE && getCount() == 0) {
            return;
        }
        super.setVisibility(visibility);
    }

    Tal vez usted necesita para establecer el fondo de adaptador de ver como transparente. Pero en mi caso, no es necesario, ya que el vacío de la vista es un simple TextView.

    • Solo para aclarar, yo creo que SwipeRefreshLayout puede contener ScrollView los niños así como AdapterViews
  6. 4

    Basado en algunas respuestas aquí y el código fuente de SwipeRefreshLayout, tengo una subclase a la vista para controlar específicamente tener un RecyclerView (o ListView) y también un «vacío» de la vista dentro de un contenedor, que es el niño.

    Se espera un diseño tales como

    <SwipeRefreshLayoutWithEmpty ...>
      <FrameLayout ...>
        <TextView android:text="List is Empty" ...>
        <RecyclerView ...>
      </FrameLayout>
    </SwipeRefreshLayoutWithEmpty>

    El código es:

    public class SwipeRefreshLayoutWithEmpty extends SwipeRefreshLayout {
    private ViewGroup container;
    public SwipeRefreshLayoutWithEmpty(Context context) {
    super(context);
    }
    public SwipeRefreshLayoutWithEmpty(Context context, AttributeSet attrs) {
    super(context, attrs);
    }
    @Override
    public boolean canChildScrollUp() {
    //The swipe refresh layout has 2 children; the circle refresh indicator
    //and the view container. The container is needed here
    ViewGroup container = getContainer();
    if (container == null) {
    return false;
    }
    //The container has 2 children; the empty view and the scrollable view.
    //Use whichever one is visible and test that it can scroll
    View view = container.getChildAt(0);
    if (view.getVisibility() != View.VISIBLE) {
    view = container.getChildAt(1);
    }
    return ViewCompat.canScrollVertically(view, -1);
    }
    private ViewGroup getContainer() {
    //Cache this view
    if (container != null) {
    return container;
    }
    //The container may not be the first view. Need to iterate to find it
    for (int i=0; i<getChildCount(); i++) {
    if (getChildAt(i) instanceof ViewGroup) {
    container = (ViewGroup) getChildAt(i);
    if (container.getChildCount() != 2) {
    throw new RuntimeException("Container must have an empty view and content view");
    }
    break;
    }
    }
    if (container == null) {
    throw new RuntimeException("Container view not found");
    }
    return container;
    }
    }

    Información completa de: https://gist.github.com/grennis/16cb2b0c7f798418284dd2d754499b43

  7. 2

    He intentado siguiente cosa. En tanto vacía de la vista, y el caso de una lista, deslizar para actualizar los datos, también fastscroll está trabajando bien, sin ningún cambio de código requeridos en la actividad.
    He puesto emptyview antes de que el listview y marcó su visibilidad a ido.
    y listview se pone después de que en el interior de SwipeToRefresh bloque.
    Código De Ejemplo –

    <FrameLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <TextView
    android:id="@+id/tv_empty_text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="32dp"
    android:gravity="center_horizontal"
    android:text="No item found"
    android:visibility="gone"/>
    <android.support.v4.widget.SwipeRefreshLayout 
    android:id="@+id/swipe"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
    android:id="@+id/lv_product"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
    </android.support.v4.widget.SwipeRefreshLayout>
    </FrameLayout>
    • Gracias. Esto funciona. Debe utilizar RelativeLayout o FrameLayout. Si utiliza LinearLayout no va a funcionar.
    • Más simple y mejor solución de trabajo
  8. 1

    Poner SwipeRefreshLayout en un FrameLayout y otros puntos de vista detrás de él.

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <LinearLayout
    android:id="@+id/your_message_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="No result"/>
    </LinearLayout>
    <android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/swipe_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <ListView
    android:id="@+id/your_list_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    </ListView>
    </android.support.v4.widget.SwipeRefreshLayout>
    </FrameLayout>
    • Esta propuesta conduce a la cuestión sin capacidad de actualización de lista vacía.
  9. 1

    ¿Por qué no incluirlo todo en el interior de SwipeRefreshLayout

    <android.support.v4.widget.SwipeRefreshLayout 
    android:id="@+id/swipe"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <ListView
    android:id="@android:id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center_horizontal"/>
    <RelativeLayout
    android:id="@android:id/empty"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    ...
    </RelativeLayout>
    </LinearLayout>
    </android.support.v4.widget.SwipeRefreshLayout>
    • Sí, yo pensaba que iba a funcionar así, pero si que algo va mal. Al deslizar hacia abajo y, a continuación, desliza el dedo de nuevo hasta que empieza a refrescar. Así que me gustaría sugerir a poner ListView directo como hijo de SwipeRefreshLayout.
    • Este error de configuración para mí también. Desplazamiento y refrescante que no funcionó como se esperaba y, a veces, yo era incapaz de desplazarse por el ListView de nuevo a la parte superior debido a que el SwipeRefreshLayout quería tomar el control. Y eso ocurrió, incluso después de añadir el código para desactivar la SwipeRefreshLayout cuando el ListView no fue desplazado a la parte superior.
  10. 1

    Probablemente tarde, Pero si aún estás frente a este problema, Aquí está la solución limpia! No hay necesidad de crear otro SwipeRefreshLayout.

    envoltura empty view en un ScrollView. Palo de ambos AdapterView y la ScrollView en un ViewGroup y la puso en la SwipeRefreshLayout

    Ejemplo:

    <android.support.v4.widget.SwipeRefreshLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
    <ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
    android:layout_width="250dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:gravity="center" />
    </ScrollView>
    </FrameLayout>
    </android.support.v4.widget.SwipeRefreshLayout>

    EDITAR

    Aquí es mucho más simple.

    comprobar si su lista es empthy. si sí, entonces hacerlo invisible. Ejemplo:

    if(lst.size() > 0) {
    mRecyclerView.setVisibility(View.VISIBLE);
    //set adapter
    }else
    {
    mRecyclerView.setVisibility(View.INVISIBLE);
    findViewById(R.id.txtNodata).setVisibility(View.VISIBLE);
    }

    esto hará que mRecyclerView todavía allí, y todos los golpes va a estar funcionando bien ahora, aunque no hay datos!

  11. 0

    Otra opción que funciona muy bien en caso de que su vacío vista no necesita ningún tipo de interacción. Por ejemplo, es un simple textview diciendo: «No hay datos que aquí.»

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <TextView
    android:id="@+id/emptyView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:visibility="visible"
    android:layout_centerInParent="true"
    android:text="@string/no_earnable_available"
    android:textSize="18dp"
    android:textColor="@color/black"
    android:background="@color/white"
    />
    <some.app.RecyclerViewSwipeToRefreshLayout
    android:id="@+id/swipe_refresh_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="4dp"
    android:background="@android:color/transparent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    >
    <android.support.v7.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/transparent"
    />
    </some.app.RecyclerViewSwipeToRefreshLayout>
    </RelativeLayout>

    Esto pone a la vista vacía detrás de la SwipeToRefreshLayout que es transparente y que contiene también un transparente RecyclerView.

    A continuación, en el código, en el lugar donde agregar los elementos para el reciclador de vista adaptador, compruebe si el adaptador está vacía, y si es así, establecer la visibilidad de la vista vacía a «visible». Y viceversa.

    El truco es que la vista está detrás de la transparente reciclador de vista, lo que significa que el reciclador de vista y su padre, el SwipeToRefreshLayout, controlará el desplazamiento cuando no hay elementos en el reciclador. El vacío de la vista detrás de no ser tocado por lo que el evento de toque será consumida por la SwipeTorefreshLayout.

    La costumbre RecyclerSwipeTorefreshLayout que debe manejar el canChildScrollUp método de la siguiente manera

    @Override
    public boolean canChildScrollUp() {
    if (recycler == null) throw new IllegalArgumentException("recycler not set!");
    else if (recycler.getAdapter().getItemCount() == 0){ //this check could be done in a more optimised way by setting a flag from the same place where you change the visibility of the empty view
    return super.canChildScrollUp();
    } else {
    RecyclerView.LayoutManager layoutManager = recycler.getLayoutManager();
    if (layoutManager instanceof LinearLayoutManager) {
    return ((LinearLayoutManager) recycler.getLayoutManager()).findFirstVisibleItemPosition() != 0 ||
    (((LinearLayoutManager) recycler.getLayoutManager()).findFirstVisibleItemPosition() == 0
    && recycler.getChildAt(0) != null && recycler.getChildAt(0).getY() < 0);
    //...

    Esto va a hacer el truco.

    ACTUALIZACIÓN:
    Por supuesto, el reciclador de vista no tiene que ser transparente en todo momento. Usted puede actualizar la transparencia activa sólo cuando el adaptador está vacía.

    Saludos!

  12. 0

    Esto era muy frustrante problema para mí, pero después de un par de horas con intentar y fallar, me encontré con esta solución.

    Con esto puedo actualizar incluso con vista vacía visible (y RecyclerView también, por supuesto)

    En mi archivo de diseño me tienen esta estructura:

    SwipeRefreshLayout
    FrameLayout
    RecyclerView
    my_empty_layout //Doesnt have to be ScrollView it can be whatever ViewGroup you want, I used LinearLayout with a single TextView child

    Código:

    ...
    adapter.notifyDataSetChanged()
    if (adapter.getItemCount() == 0) {
    recyclerView.setVisibility(View.GONE);
    emptyView.setVisibility(View.VISIBLE);
    }
    else {
    recyclerView.setVisibility(View.VISIBLE);
    emptyView.setVisibility(View.GONE);
    }
  13. 0

    Esto funcionó para mí

    <FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/lighter_white">
    <android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/swipeContainer"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:background="@color/silver"
    android:layout_marginTop="10dp"
    android:divider="@android:color/transparent"
    android:dividerHeight="8dp"
    android:padding="4dp"/>
    </android.support.v4.widget.SwipeRefreshLayout>
    <TextView
    android:id="@+id/empty"
    android:text="@string/strNoRecordsFound"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:textColor="@android:color/black"
    android:alpha="0.5"
    android:gravity="center">
    </TextView>
    </FrameLayout>
  14. 0

    Usted puede ser sólo uso NestedScrollView en SwipeRefreshLayout con un solo contenedor.
    A continuación se muestra la lista de buggy uso mRecyclerView.setNestedScrollingEnabled(false);

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- some toolbar -->
    <android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/conversationFragment_swipeRefresh"
    android:layout_alignParentBottom="true"
    android:layout_below="@+id/some_toolbar"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
    android:id="@+id/conversationFragment_noResultText"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="@string/FragmentConversations_empty"
    android:layout_centerHorizontal="true" />
    <android.support.v7.widget.RecyclerView
    android:id="@+id/conversationFragment_recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
    </FrameLayout>
    </android.support.v4.widget.NestedScrollView>
    </android.support.v4.widget.SwipeRefreshLayout>
    </RelativeLayout>
  15. -1

    Como he mencionado aquí, he hecho esto para RecyclerView:

    He utilizado clickable="true" como el de abajo, con vacío RecyclerView:

    mRecyclerView.setVisibility(View.VISIBLE);
    mRecyclerView.setClickable(true);
    myText.setVisibility(View.VISIBLE);

    xml de diseño:

    <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/swipeRefreshKartvizitKisilerim"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <android.support.v7.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
    </android.support.v4.widget.SwipeRefreshLayout>
    <TextView
    android:id="@+id/myText"
    android:visibility="gone"
    android:text="@string/noListItem"
    android:textSize="18sp"
    android:layout_centerInParent="true"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
    </RelativeLayout>

    RecyclerView tiene la altura match_parent y SwipeRefresh ha wrap_content. Cuando no es el elemento en la lista, no te olvides de hacer que el texto gone.

Dejar respuesta

Please enter your comment!
Please enter your name here