Jak zaimplementować Pull-to-Refresh Androida

W aplikacjach na Androida, takich jak Twitter (oficjalna aplikacja), gdy napotkasz ListView, możesz go pociągnąć w dół (i odbije się po wydaniu), aby odświeżyć zawartość.

Zastanawiam się, jaki jest najlepszy sposób, Twoim zdaniem, aby to zrealizować?

Niektóre możliwości, które mógłbym wymyślić:

  1. element na górze ListView - jednak nie sądzę, aby przewijanie z powrotem do pozycji 1 (opartej na 0) z animacją na ListView było łatwym zadaniem.
  2. inny widok poza ListView - ale muszę zadbać o przesunięcie pozycji ListView w dół, gdy jest wyciągany, i nie jestem pewien, czy możemy wykryć, czy przeciąganie do ListView nadal naprawdę przewija elementy na ListView.

Jakieś zalecenia?

P. S. ciekawe kiedy ukaże się oficjalny kod źródłowy aplikacji Twitter. Wspomniano, że zostanie wydany, ale minęło 6 miesięcy i nie słyszeliśmy o tym od tego czasu.

Author: Michael Celey, 2011-01-03

14 answers

W końcu Google wydało oficjalną wersję biblioteki pull-to-refresh!

Nazywa się SwipeRefreshLayout, wewnątrz biblioteki wsparcia, a dokumentacja jest proszę.:

1) dodaj SwipeRefreshLayout jako rodzica widoku, który będzie traktowany jako pull w celu odświeżenia układu. (Wziąłem ListView jako przykład, może to być dowolny View Jak LinearLayout, ScrollView itd.)

<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/pullToRefresh"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>

2) Dodaj słuchacza do swojej klasy

protected void onCreate(Bundle savedInstanceState) {
    SwipeRefreshLayout pullToRefresh = findViewById(R.id.pullToRefresh);
    pullToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            refreshData(); // your code
            pullToRefresh.setRefreshing(false);
        }
    });
}

Możesz również zadzwonić pullToRefresh.setRefreshing(true/false); zgodnie z Twoim wymagania.

 216
Author: Randy Sugianto 'Yuku',
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-10 15:57:20

Próbowałem zaimplementować pull to refresh komponentu, jest on daleki od kompletnego ale pokazuje możliwą implementację, https://github.com/johannilsson/android-pulltorefresh .

Główna logika jest zaimplementowana w PullToRefreshListView, która rozszerza ListView. wewnętrznie kontroluje przewijanie widoku nagłówka za pomocą smoothScrollBy (poziom API 8). widget został zaktualizowany o wsparcie dla 1.5 i nowszych, proszę przeczytać README dla wsparcia 1.5 choć.

W Twoim układy po prostu dodajesz w ten sposób.

<com.markupartist.android.widget.PullToRefreshListView
    android:id="@+id/android:list"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
    />
 78
Author: Johan Berg Nilsson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-24 16:00:03

Zaimplementowałem również solidną, otwartoźródłową, łatwą w użyciu i wysoce konfigurowalną bibliotekę PullToRefresh dla Androida. ListView można zastąpić PullToRefreshListView, jak opisano w dokumentacji na stronie projektu.

Https://github.com/erikwt/PullToRefresh-ListView

 53
Author: Erik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-07 02:03:24

Najprostszy sposób, jak sądzę, jest dostarczany przez Bibliotekę wsparcia dla Androida:

Android.wsparcie.v4.widget.SwipeRefreshLayout;

Po zaimportowaniu możesz zdefiniować swój układ w następujący sposób:

  <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/refresh"
        android:layout_height="match_parent"
        android:layout_width="match_parent">
    <android.support.v7.widget.RecyclerView
        xmlns:recycler_view="http://schemas.android.com/apk/res-auto"
        android:id="@android:id/list"
        android:theme="@style/Theme.AppCompat.Light"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/button_material_light"
        >

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

Zakładam, że używasz recycler view zamiast listview. Jednak listview nadal działa, więc wystarczy zastąpić recyclerview listview i zaktualizować odniesienia w kodzie java (Fragment).

W swoim fragmencie aktywności najpierw wdrażasz Interfejs, SwipeRefreshLayout.OnRefreshListener: i, e

public class MySwipeFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener{
private SwipeRefreshLayout swipeRefreshLayout;

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_item, container, false);
        swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.refresh);
        swipeRefreshLayout.setOnRefreshListener(this);
}


 @Override
  public void onRefresh(){
     swipeRefreshLayout.setRefreshing(true);
     refreshList();
  }
  refreshList(){
    //do processing to get new data and set your listview's adapter, maybe  reinitialise the loaders you may be using or so
   //when your data has finished loading, cset the refresh state of the view to false
   swipeRefreshLayout.setRefreshing(false);

   }
}
Mam nadzieję, że to pomoże masom]}
 35
Author: larrytech,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-15 18:28:08

W tym linku znajdziesz fork słynnego widoku PullToRefresh, który ma nowe ciekawe implementacje, takie jak PullTorRefreshWebView lub PullToRefreshGridView lub możliwość dodania PullToRefresh na dolnej krawędzi listy.

Https://github.com/chrisbanes/Android-PullToRefresh

A najlepsze jest to, że działa idealnie w Androidzie 4.1 (Normalny PullToRefresh nie działa)

 21
Author: Aracem,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-10 14:48:33

Mam bardzo łatwy sposób, aby to zrobić, ale teraz na pewno jest niezawodny sposób Oto Mój kod PullDownListView.java

package com.myproject.widgets;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;

/**
 * @author Pushpan
 * @date Nov 27, 2012
 **/
public class PullDownListView extends ListView implements OnScrollListener {

    private ListViewTouchEventListener mTouchListener;
    private boolean pulledDown;

    public PullDownListView(Context context) {
        super(context);
        init();
    }

    public PullDownListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public PullDownListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        setOnScrollListener(this);
    }

    private float lastY;

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            lastY = ev.getRawY();
        } else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
            float newY = ev.getRawY();
            setPulledDown((newY - lastY) > 0);
            postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (isPulledDown()) {
                        if (mTouchListener != null) {
                            mTouchListener.onListViewPulledDown();
                            setPulledDown(false);
                        }
                    }
                }
            }, 400);
            lastY = newY;
        } else if (ev.getAction() == MotionEvent.ACTION_UP) {
            lastY = 0;
        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        setPulledDown(false);
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }

    public interface ListViewTouchEventListener {
        public void onListViewPulledDown();
    }

    public void setListViewTouchListener(
            ListViewTouchEventListener touchListener) {
        this.mTouchListener = touchListener;
    }

    public ListViewTouchEventListener getListViewTouchListener() {
        return mTouchListener;
    }

    public boolean isPulledDown() {
        return pulledDown;
    }

    public void setPulledDown(boolean pulledDown) {
        this.pulledDown = pulledDown;
    }
}

Wystarczy zaimplementować ListViewTouchEventListener w swojej aktywności, w której chcesz użyć tego ListView i ustawić listener

Mam to zaimplementowane w PullDownListViewActivity

package com.myproject.activities;

import android.app.Activity;
import android.os.Bundle;

/**
 * @author Pushpan
 *
 */
public class PullDownListViewActivity extends Activity implements ListViewTouchEventListener {

    private PullDownListView listView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        listView = new PullDownListView(this);
        setContentView(listView);
        listView.setListViewTouchListener(this);

        //setItems in listview
    }

    public void onListViewPulledDown(){
        Log.("PullDownListViewActivity", "ListView pulled down");
    }
}

U mnie działa:)

 18
Author: Pushpan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-27 11:45:02

Aby zaimplementować Pull-to-Refresh Androida wypróbuj ten fragment kodu,

<android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/pullToRefresh"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    <ListView
        android:id="@+id/lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>

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

Klasa aktywności:

ListView lv = (ListView) findViewById(R.id.lv);
SwipeRefreshLayout pullToRefresh = (SwipeRefreshLayout) findViewById(R.id.pullToRefresh);


lv.setAdapter(mAdapter);

pullToRefresh.setOnRefreshListener(new OnRefreshListener() {

        @Override
        public void onRefresh() {
            // TODO Auto-generated method stub

            refreshContent();

        }
    });



private void refreshContent(){ 

     new Handler().postDelayed(new Runnable() {
            @Override public void run() {
                pullToRefresh.setRefreshing(false);
            }
        }, 5000);

 }
 18
Author: mani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-20 08:51:10

Nikt nie wspomniał o nowym typie "Pull to refresh", który pojawia się na pasku akcji, jak w aplikacji Google Now lub Gmail.

Istnieje Biblioteka ActionBar-PullToRefresh , która działa dokładnie tak samo.

 9
Author: tomrozb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-21 11:10:31

Uwaga istnieją problemy z UX do czynienia podczas wdrażania na Androida i WP.

" świetnym wskaźnikiem, dlaczego Projektanci / deweloperzy nie powinni wdrażać pull-to-refresh w stylu aplikacji na iOS, jest to, że Google i ich zespoły nigdy nie używają pull-to-refresh na Androidzie, podczas gdy używają go w iOS. "

Https://plus.google.com/109453683460749241197/posts/eqYxXR8L4eb

 7
Author: uobroin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-23 20:09:02

Jeśli nie chcesz, aby twój program wyglądał jak program iPhone, który jest siłą dopasowany do Androida, staraj się bardziej natywny wygląd i zrób coś podobnego do Gingerbread:

alt text

 4
Author: Lie Ryan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-05 14:34:28

Napisałem pull, aby odświeżyć komponent tutaj: https://github.com/guillep/PullToRefresh Działa event, jeśli lista nie ma elementów, i Przetestowałem go na > = 1.6 telefony z Androidem.

Każda sugestia lub poprawa jest doceniana:)

 4
Author: Guille Polito,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-30 20:05:21

Myślę, że najlepsza biblioteka to: https://github.com/chrisbanes/Android-PullToRefresh .

Współpracuje z:

ListView
ExpandableListView
GridView
WebView
ScrollView
HorizontalScrollView
ViewPager
 2
Author: Jossy Paul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-25 05:13:24

Aby pobrać najnowszy Pull Lollipop-odświeżyć:

  1. pobierz najnowszą bibliotekę Lollipop SDK i Dodatki / Android support library
  2. Ustaw cel budowania projektu na Androida 5.0 (w przeciwnym razie pakiet wsparcia może mieć błędy z zasobami)
  3. Zaktualizuj swój libs / Android-support-v4.jar to 21st version
  4. Użyj android.support.v4.widget.SwipeRefreshLayout plus android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener

Szczegółowy przewodnik można znaleźć tutaj: http://antonioleiva.com/swiperefreshlayout/

Plus za ListView polecam do przeczytaj o canChildScrollUp() w komentarzach;)

 1
Author: goRGon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-19 20:34:45

Bardzo ciekawe Pull-to-Refreshby Yalantis. Gif dla iOS, ale można to sprawdzić:) [6]}

<com.yalantis.pulltorefresh.library.PullToRefreshView
android:id="@+id/pull_to_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
    android:id="@+id/list_view"
    android:divider="@null"
    android:dividerHeight="0dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

 1
Author: edbaev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-19 13:42:39