Cara menerapkan Android Pull-to-Refresh

433

Dalam aplikasi Android seperti Twitter (aplikasi resmi), ketika Anda menjumpai ListView, Anda dapat menariknya ke bawah (dan itu akan bangkit kembali ketika dirilis) untuk menyegarkan konten.

Saya ingin tahu apa cara terbaik, menurut Anda, untuk mengimplementasikannya?

Beberapa kemungkinan yang dapat saya pikirkan:

  1. Item di atas ListView - namun saya tidak berpikir bergulir kembali ke posisi item 1 (berbasis 0) dengan animasi pada ListView adalah tugas yang mudah.
  2. Pandangan lain di luar ListView - tetapi saya harus berhati-hati dalam memindahkan posisi ListView ke bawah ketika ditarik, dan saya tidak yakin apakah kita dapat mendeteksi apakah drag-touch ke ListView masih benar-benar menggulir item pada ListView.

Ada rekomendasi?

PS Saya ingin tahu kapan kode sumber aplikasi Twitter resmi dirilis. Telah disebutkan bahwa itu akan dirilis, tetapi 6 bulan telah berlalu dan kami belum mendengarnya sejak itu.

Randy Sugianto 'Yuku'
sumber
Apakah fungsi ini dapat diimplementasikan dalam TableLayout yang dibuat secara dinamis. Tolong Bantu .....
Arun Badole
github.com/fruitranger/PulltorefreshListView adalah implementasi saya yang lain. Dukungan halus dan multi-sentuh.
Changwei Yao
6
Terkait: "Tarik-untuk-menyegarkan": pola anti UI pada Android adalah artikel yang menyatakan bahwa UI ini bukan sesuatu yang harus digunakan pada Android dan memicu banyak diskusi tentang kesesuaiannya.
blahdiblah
29
Seseorang harus memberi tahu Google karena versi terbaru Gmail untuk Android menggunakan "pola anti" ini.
Nick
4
Tarik untuk menyegarkan adalah (dan telah lama) pola standar yang diadopsi di iOS dan Android dan itu sangat alami, sehingga diskusi anti-pola ini sudah usang. Pengguna akan berharap untuk melihatnya dan berperilaku seperti itu.
Martin Marconcini

Jawaban:

311

Akhirnya, Google merilis versi resmi perpustakaan tarik-untuk-menyegarkan!

Itu disebut SwipeRefreshLayout, di dalam perpustakaan dukungan, dan dokumentasinya ada di sini :

  1. Tambahkan SwipeRefreshLayoutsebagai tampilan induk yang akan diperlakukan sebagai tarikan untuk menyegarkan tata letak. (Saya mengambil ListViewsebagai contoh, dapat saja Viewseperti LinearLayout, ScrollViewdll)

    <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. Tambahkan pendengar ke kelas Anda

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

Anda juga dapat menelepon pullToRefresh.setRefreshing(true/false);sesuai kebutuhan Anda.

MEMPERBARUI

Perpustakaan dukungan Android telah usang dan telah digantikan oleh AndroidX. Tautan ke perpustakaan baru dapat ditemukan di sini .

Anda juga perlu menambahkan ketergantungan berikut ke proyek Anda:

implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'

ATAU

Anda dapat pergi ke Refactor >> Migrasikan ke AndroidX dan Android Studio akan menangani dependensi untuk Anda.

Randy Sugianto 'Yuku'
sumber
3
dapatkah saya menggunakan ProgressBar alih-alih Skema Warna di SwipeRefreshLayout?
pablobaldez
54
1 April '14 - dan itu bukan lelucon
aeracode
2
Pedoman
david72
80

Saya telah berupaya menerapkan komponen tarik untuk menyegarkan, masih jauh dari selesai tetapi menunjukkan kemungkinan penerapan, https://github.com/johannilsson/android-pulltorefresh .

Logika utama diimplementasikan dalam PullToRefreshListViewperluasan itu ListView. Secara internal ia mengontrol gulir tampilan tajuk menggunakan smoothScrollBy(API Level 8). Widget sekarang diperbarui dengan dukungan untuk 1.5 dan kemudian, harap baca README untuk dukungan 1.5.

Di layout Anda, Anda cukup menambahkannya seperti ini.

<com.markupartist.android.widget.PullToRefreshListView
    android:id="@+id/android:list"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
    />
Johan Berg Nilsson
sumber
3
Hai johan, saya sudah mengunduh kode sampel Anda. Ini bekerja di perangkat Android 2.2 tetapi tidak bekerja di perangkat 2.1. Saya pikir karena menggunakan metode smoothScrollBy yang hanya tersedia di 2.2 atau lebih baru, apakah benar? Dan apakah Anda punya ide untuk menerapkan efek ini ke versi 2.1 atau yang lebih lama? Terima kasih
Ya itu benar seperti yang saya nyatakan dalam jawaban smoothScrollBy diperkenalkan di API Level 8 (2.2). Saya belum menemukan cara yang tepat untuk mengimplementasikannya untuk versi lain, tetapi saya kira itu seharusnya memungkinkan untuk port implementasi smoothScrollBy tapi saya kira diskusi itu harus disimpan di lokasi proyek dan bukan pada stack overflow?
Johan Berg Nilsson
Apakah sengaja bahwa id adalah @ + id / android: list dan bukan @android: id / list, itu terlihat aneh? Proyek ini melemparkan kesalahan inflasi di sini di pihak saya, saya saat ini sedang memeriksa itu ...
Mathias Conradt
12
Ini adalah perpustakaan terbaik untuk menarik untuk menyegarkan yang saya temukan .. github.com/chrisbanes/Android-PullToRefresh . Ini bekerja dengan ListViews, GridViews, dan Tampilan Web. Juga telah Tarik ke atas untuk menyegarkan pola diterapkan.
rOrlig
1
Bagaimana cara menambahkan proyek ke folder perpustakaan saat mengerjakan Ide Intellij? Adakah yang bisa membantu saya?
Mustafa Güven
55

Saya juga menerapkan pustaka PullToRefresh yang kuat, open source, mudah digunakan dan sangat dapat disesuaikan untuk Android. Anda dapat mengganti ListView Anda dengan PullToRefreshListView seperti yang dijelaskan dalam dokumentasi pada halaman proyek.

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

Erik
sumber
Saya mencoba semua implementasi yang tercantum di sini dan milik Anda adalah yang terbaik, dalam hal penerapan sederhana / murni / mulus untuk menyegarkan (tidak ada ketukan untuk menyegarkan keanehan seperti Johan). Terima kasih!
Gady
1
Bisakah ini menggantikan ListView standar agar berfungsi dengan ListActivity, ListFragment, dan sebagainya?
davidcsb
Ya, berikan saja PullToRefreshListView id yang benar. Dalam XML: android: id = "@ android: id / list"
Erik
1
ini benar-benar luar biasa! Google membawa saya ke sini, dan melihat contoh-contohnya, Anda terlihat paling mudah untuk diterapkan. bravo dan terima kasih tuan!
Evan R.
Komponen yang dirancang dengan sangat masuk akal, bagus dan sederhana. Ini seharusnya menjadi jawaban yang diterima.
Adam
42

Cara termudah yang menurut saya disediakan oleh pustaka dukungan android:

android.support.v4.widget.SwipeRefreshLayout;

setelah itu diimpor maka Anda dapat menetapkan tata letak sebagai berikut:

  <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>

Saya berasumsi bahwa Anda menggunakan tampilan pendaur ulang daripada tampilan daftar. Namun, listview masih berfungsi sehingga Anda hanya perlu mengganti recyclerview dengan listview dan memperbarui referensi dalam kode java (Fragment).

Di fragmen aktivitas Anda, Anda pertama-tama mengimplementasikan antarmuka,: SwipeRefreshLayout.OnRefreshListeneri, 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);

   }
}

Semoga ini bisa membantu massa

larrytech
sumber
Ini bekerja dengan baik. Padahal, satu hal yang berkenaan dengan setRefreshing: "Jangan panggil ini saat penyegaran dipicu oleh gerakan gesek" seperti yang dijelaskan dalam developer.android.com/reference/android/support/v4/widget/…
gabriel14
Kerja bagus! Terima kasih.
technik
22

Di tautan ini, Anda dapat menemukan percabangan dari tampilan terkenal PullToRefreshyang memiliki implementasi baru yang menarik seperti PullTorRefreshWebViewatau PullToRefreshGridViewatau kemungkinan untuk menambahkan PullToRefreshdi tepi bawah daftar.

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

Dan yang terbaik adalah itu berfungsi sempurna di Android 4.1 (yang normal PullToRefreshtidak berfungsi)

Aracem
sumber
3
Sebuah komentar besar di bagian atas readme menunjukkan: PROYEK INI TIDAK LAMA DIPERTAHANKAN. Bagaimanapun, lib ini adalah yang terbaik yang pernah saya lihat sejauh ini! Kerja bagus!
Milton
3
Hanya karena itu tidak lagi dipertahankan, tidak berarti itu tidak baik. Masih menggunakannya untuk semua kebutuhan saya untuk menyegarkan :)
Muz
18

Saya memiliki cara yang sangat mudah untuk melakukan ini tetapi sekarang yakin dengan cara yang sangat mudah. ​​Ada kode saya 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;
    }
}

Anda hanya perlu menerapkan ListViewTouchEventListener pada aktivitas Anda di mana Anda ingin menggunakan ListView ini dan mengatur pendengar

Saya sudah menerapkannya di 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");
    }
}

Ini bekerja untuk saya :)

Pushpan
sumber
18

Untuk menerapkan Android Pull-to-Refresh, coba bagian kode ini,

<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>

Kelas aktivitas:

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);

 }
mani
sumber
1
Terima kasih. Itu sangat membantu saya
Arpan Sharma
9

Tidak ada yang menyebutkan jenis baru "Tarik untuk menyegarkan" yang ditampilkan di atas bilah tindakan seperti di Google Now atau aplikasi Gmail.

Ada perpustakaan ActionBar-PullToRefresh yang berfungsi persis sama.

Tomrozb
sumber
7

Perhatikan ada masalah UX yang harus dihadapi ketika menerapkan pada Android dan WP.

"Indikator hebat mengapa desainer / pengembang tidak boleh menerapkan tarikan untuk menyegarkan dalam gaya yang dilakukan aplikasi iOS adalah bagaimana Google dan tim mereka tidak pernah menggunakan tarikan untuk menyegarkan di Android sementara mereka menggunakannya di iOS."

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

uobroin
sumber
3
Saya tahu ini sudah lebih dari setahun tetapi aplikasi Gmail menggunakan pull-to-refresh. Namun itu tidak persis sama dalam hal UI, daftar tidak gulir ke bawah, melainkan tampilan baru muncul di bagian atas layar.
ashishduh
4

Jika Anda tidak ingin program Anda terlihat seperti program iPhone yang dipasangkan secara paksa ke Android, bertujuan untuk tampilan dan rasa yang lebih asli dan lakukan sesuatu yang mirip dengan Gingerbread:

teks alternatif

Lie Ryan
sumber
2
@ Rob: Maksud saya memiliki bayangan oranye di bagian atas daftar ketika Anda overpull, alih-alih membuat daftar bangkit kembali seperti pada iPhone. Ini dimaksudkan sebagai komentar (bukan jawaban), tetapi komentar tidak dapat memiliki gambar.
Lie Ryan
Ahh, maaf, Ide bagus. Saya belum bermain dengan roti jahe, jadi belum melihat efeknya. Masih menunggu google untuk menggulungnya ke nexus.
Rob
9
Saya memiliki Gingerbread dan cahaya oranye berfungsi dengan baik ketika daftar statis. Tetapi pull-down-refresh adalah mekanisme UI yang bagus untuk menyegarkan daftar dinamis. Meskipun lazim di dunia iOS, ini adalah trik UI yang tidak terasa aneh di ekosistem Android. Saya sangat menyarankan Anda memeriksanya di aplikasi Twitter resmi. :)
Thierry-Dimitri Roy
Perilaku asli di sini adalah untuk menunjukkan bahwa Anda telah mencapai akhir daftar. Mengambil ini, dan melakukan penyegaran sama sekali bukan asli karena Anda tidak melakukan apa yang platform lakukan. Ini berarti Anda lebih cenderung mengejutkan pengguna. Saya tentu tidak akan berharap atau ingin menyegarkan hanya karena saya sampai di akhir daftar. Tarik ke bawah untuk menyegarkan jauh lebih intuitif dan jelas. Dan ketika aplikasi twitter asli menggunakannya saya pikir adil untuk mengatakan itu adalah konsep UI yang banyak orang kenal.
steprobe
4

Saya telah menulis tarikan untuk menyegarkan komponen di sini: https://github.com/guillep/PullToRefresh Ini berfungsi jika daftar tidak memiliki item, dan saya sudah mengujinya pada> = 1,6 ponsel android.

Setiap saran atau peningkatan dihargai :)

Guille Polito
sumber
1

Untuk mendapatkan Lollipop Pull-To Refresh terbaru:

  1. Unduh perpustakaan terbaru Lollipop SDK dan Extras / Android
  2. Tetapkan Target Bangun Proyek ke Android 5.0 (jika tidak, paket dukungan dapat memiliki kesalahan dengan sumber daya)
  3. Perbarui libs / android-support-v4.jar Anda ke versi 21
  4. Gunakan android.support.v4.widget.SwipeRefreshLayoutplusandroid.support.v4.widget.SwipeRefreshLayout.OnRefreshListener

Panduan lengkap dapat ditemukan di sini: http://antonioleiva.com/swiperefreshlayout/

Plus untuk ListView saya sarankan untuk membaca tentang canChildScrollUp()di komentar;)

GoRGon
sumber
Plus satu hanya untuk menyebutkan canChildScrollUp (). Sangat penting!
Petro
1

Pull-to-Refresh yang sangat menarik oleh Yalantis . Gif untuk iOS, tetapi Anda dapat memeriksanya :)

<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" />

edbaev
sumber
0

Pertama-tama kita harus tahu apa itu Tarik untuk menyegarkan tata letak di android. kita dapat memanggil tarikan untuk menyegarkan di Android sebagai gesek ke penyegaran. ketika Anda menggeser layar dari atas ke bawah, ia akan melakukan beberapa tindakan berdasarkan setOnRefreshListener.

Berikut tutorial yang menunjukkan tentang cara menerapkan tarik android untuk menyegarkan. Saya harap ini membantu.

Hasan Raza
sumber