Android Pull-to-Refresh nasıl uygulanır?


432

Twitter (resmi uygulama) gibi Android uygulamalarında, bir ListView ile karşılaştığınızda, içeriği yenilemek için aşağı çekebilir (ve yayınlandığında geri döner).

Bunu uygulamaya koymanın en iyi yolunun ne olduğunu merak ediyorum.

Düşünebileceğim bazı olasılıklar:

  1. ListView üstünde bir öğe - ancak ListView animasyon ile madde konumu 1 (0 tabanlı) geri kaydırma sanmıyorum kolay bir görevdir.
  2. ListView dışında başka bir görünüm - ama ben çekildiğinde ListView konumunu aşağı taşımak için dikkat gerekir, ve biz ListView sürükleme dokunur hala gerçekten ListView öğeleri kaydırmak olup olmadığını tespit edemiyorum emin değilim.

Herhangi bir tavsiye?

PS: Resmi Twitter uygulaması kaynak kodunun ne zaman yayınlandığını merak ediyorum. Serbest bırakılacağı belirtildi, ancak 6 ay geçti ve o zamandan beri bunu duymadık.


Bu işlevsellik dinamik olarak oluşturulmuş bir TableLayout içinde uygulanabilir mi? Lütfen Yardım .....
Arun Badole

github.com/fruitranger/PulltorefreshListView bir başka uygulamam. Pürüzsüz ve çoklu dokunma desteği.
Changwei Yao

6
İlgili: “Çekme Yenilemek için”: Android'de bir anti UI desen bu UI savunarak bir makale değil Android'de kullanılan ve uygunluğu hakkında tartışma bir sürü yol açtı gereken bir şey.
blahdiblah

29
Android için Gmail'in en son sürümü bu "anti-desen" kullandığından, Google'a birileri bildirmelidir.
Nick

4
Yenilemek için çekin, iOS ve Android'de kabul edilen standart bir modeldir (ve bir süredir olmuştur) ve çok doğaldır, bu nedenle bu anti-desen tartışması eskidir. Kullanıcılar onu görmeyi ve böyle davranmayı bekleyeceklerdir.
Martin Marconcini

Yanıtlar:


310

Son olarak, Google, yenilemek için açılan kütüphanenin resmi bir sürümünü yayınladı!

SwipeRefreshLayoutDestek kütüphanesinin içinde çağrılır ve dokümantasyon burada :

  1. SwipeRefreshLayoutDüzeni yenilemek için çekme olarak değerlendirilecek bir görünüm üst öğesi olarak ekleyin . (I aldı ListViewbir örnek olarak, herhangi bir olabilir, Viewgibi LinearLayout, ScrollViewvs.)

    <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. Sınıfınıza bir dinleyici ekleyin

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

Ayrıca pullToRefresh.setRefreshing(true/false);şartının olarak arayabilirsiniz .

GÜNCELLEME

Android destek kitaplıkları kullanımdan kaldırıldı ve yerini AndroidX aldı. Yeni kütüphaneye bağlantı burada bulunabilir .

Ayrıca, projenize aşağıdaki bağımlılığı eklemeniz gerekir:

implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'

VEYA

Refactor'a gidebilirsiniz >> AndroidX'e geçin ve Android Studio sizin için bağımlılıkları ele alacaktır.


3
RefreshLayout'ta Renk Düzeni yerine bir ProgressBar kullanabilir miyim?
pablobaldez

54
1 Nisan 14 - ve bu bir şaka değildi
aeracode


80

Bileşeni yenilemek için bir çekme uygulama girişiminde bulundum , tam olmaktan uzak, ancak olası bir uygulamayı gösteriyor, https://github.com/johannilsson/android-pulltorefresh .

Ana mantık PullToRefreshListViewbu kapsamda genişler ListView. Dahili olarak smoothScrollBy(API Seviye 8) kullanarak bir başlık görünümünün kaydırılmasını kontrol eder . Widget şimdi 1.5 ve sonraki sürümler için destekle güncellenmiştir, lütfen yine de 1.5 numaralı destek için README'yi okuyun.

Yerleşimlerinize basitçe böyle ekleyin.

<com.markupartist.android.widget.PullToRefreshListView
    android:id="@+id/android:list"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
    />

3
Merhaba johan, örnek kodunuzu indirdim. Android 2.2 cihazında çalıştı, ancak 2.1 cihazında çalıştı. Ben sadece 2.2 veya daha sonra kullanılabilir, smoothScrollBy yöntemi kullandığından , doğru olduğunu düşünüyorum? Ve bu etkiyi 2.1 veya daha eski bir sürüme uygulamak için herhangi bir fikriniz var mı? Teşekkürler

Evet, smoothScrollBy'nin API Seviye 8 (2.2) 'de tanıttığı cevapta belirttiğim gibi bu doğru. Henüz diğer sürümler için uygulamak için uygun bir yol bulamadım, ama bu smoothScrollBy uygulama portlamak mümkün olmalı ama yığın tartışma taşması değil proje sitesinde tutulmalıdır sanırım?
Johan Berg Nilsson

Kimliğin @ + id / android: list olması değil @android: id / list olması garip görünüyor mu? Proje burada benim tarafımda bir enflasyon hatası atıyor, şu anda bunu kontrol ediyorum ...
Mathias Conradt

12
Bu buldum yenilemek için çekme için en iyi kütüphane .. github.com/chrisbanes/Android-PullToRefresh . ListViews, GridViews ve Webviews ile çalışır. Ayrıca desen yenilemek için Pull up uygulandı.
rOrlig

1
Intellij Idea üzerinde çalışırken projeyi kitaplık klasörüne nasıl eklerim? Birisi bana yardım edebilir mi?
Mustafa Güven

55

Ayrıca Android için sağlam, açık kaynaklı, kullanımı kolay ve son derece özelleştirilebilir PullToRefresh kütüphanesi uyguladım. ListView, proje sayfasındaki belgelerde açıklandığı gibi PullToRefreshListView ile değiştirebilirsiniz.

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


Burada listelenen tüm uygulamaları denedim ve sizin için en iyisi, uygulamayı yenilemek için basit / saf / pürüzsüz bir çekme açısından (Johan'ınki gibi garipliği yenilemek için musluk yok). Teşekkürler!
Gady

1
Bu, standart bir ListView yerine ListActivity, ListFragment ve benzeri ile çalışabilir mi?
davidcesarino

Evet, PullToRefreshListView öğesine doğru kimliği vermeniz yeterlidir. XML'de: android: id = "@ android: id / list"
Erik

1
bu kesinlikle harika! google beni buraya getirdi ve örnekleri inceleyerek, uygulaması en kolay olanı. bravo ve teşekkür ederim efendim!
Evan R.

Çok hassas bir şekilde tasarlanmış bileşen, hoş ve basit. Bu kesinlikle kabul edilen cevap olmalıdır.
Adam

42

Bence en kolay yol android destek kütüphanesi tarafından sağlandığı gibidir:

android.support.v4.widget.SwipeRefreshLayout;

içe aktarıldıktan sonra düzeninizi aşağıdaki gibi tanımlayabilirsiniz:

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

Listview yerine recycler view kullandığınızı varsayıyorum. Ancak, listview yine de çalışır, bu yüzden geri dönüşüm görünümünü listview ile değiştirmeniz ve java kodundaki (Fragment) referansları güncellemeniz yeterlidir.

Etkinlik parçanızda önce arabirimi uygularsınız 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);

   }
}

Umarım bu kitlelere yardımcı olur


İyi çalışıyor. Gerçi, ilgili bir şey setRefreshing: anlatıldığı gibi "yenileme bir sürükleme hareketi tarafından tetiklenmesi durumunda bu deme" developer.android.com/reference/android/support/v4/widget/...
gabriel14

Aferin! Teşekkürler.
technik

22

Bu linkte, ünlü PullToRefreshgörünümün yeni bir uygulaması olan PullTorRefreshWebViewveya bir listenin alt kenarına PullToRefreshGridViewa ekleme olasılığı olan bir çatal bulabilirsiniz PullToRefresh.

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

Ve en iyisi Android 4.1'de mükemmel çalışması (normal PullToRefreshçalışmıyor)


3
Benioku dosyasının üstündeki büyük bir yorum şunu gösterir: BU PROJE BAKIM YOKTUR. Her neyse, bu lib şimdiye kadar gördüğüm en iyisi! Harika iş!
Milton

3
Artık bakımının yapılmaması, iyi olmadığı anlamına gelmez. Yine de ihtiyaçları karşılamak için tüm
çekimlerim için kullan

18

Bunu yapmak için çok kolay bir yol var ama şimdi onun kusursuz yolu var Benim 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;
    }
}

ListViewTouchEventListener'ı bu ListView'ı kullanmak ve dinleyiciyi ayarlamak istediğiniz etkinliğinize uygulamanız yeterlidir.

PullDownListViewActivity'de uyguladım

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

Benim için çalışıyor :)


18

Android Pull-to-Refresh'i uygulamak için bu kod parçasını deneyin,

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

Faaliyet sınıfı:

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

 }

1
Teşekkür ederim. Gerçekten bana yardımcı oldu
Arpan Sharma

9

Hiç kimse, Google Asistan veya Gmail uygulamasında olduğu gibi işlem çubuğunun üstünde gösterilen yeni "Yenilemek için çek" türünden bahsetmedi.

Aynı şekilde çalışan bir kütüphane ActionBar-PullToRefresh var.


7

Android ve WP'de uygularken ele alınması gereken UX sorunlarının olduğunu unutmayın.

"Tasarımcıların / geliştiricilerin iOS uygulamalarının tarzında neden yenileme-yenileme uygulamaması gerektiğinin harika bir göstergesi, Google ve ekiplerinin iOS'ta kullanırken Android'de asla yenileme-yenileme özelliğini kullanmadığıdır."

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


3
Bunun bir yıldan eski olduğunu biliyorum, ancak Gmail uygulaması yenilemek için pull-up kullanıyor. Bununla birlikte, kullanıcı arayüzü açısından tam olarak aynı değildir, liste aşağı kaydırılmaz, ekranın üstünde yeni bir görünüm gösterir.
ashishduh

4

Programınızın Android'e zorlanmış bir iPhone programı gibi görünmesini istemiyorsanız, daha doğal bir görünüm ve his hedefleyin ve Gingerbread'e benzer bir şey yapın:

alternatif metin


2
@Rob: Listeyi iPhone'da olduğu gibi geri döndürmek yerine, fazla doldurduğunuzda listenin üstünde turuncu gölgeye sahip olmak istedim. Bu bir yorum anlamına gelir (cevap değil), ancak yorumların görüntüsü olamaz.
Lie Ryan

Ahh, üzgünüm, harika fikir. Henüz zencefilli kurabiye ile oynamadım, bu yüzden etkisini görmemiştim. Hala google'ın bağlantı noktasına geçmesini bekliyor.
Rob

9
Gingerbread var ve bir liste statik olduğunda turuncu parlaklık harika çalışıyor. Ancak, aşağı açılır yenileme, dinamik bir listeyi yenilemek için harika bir kullanıcı arayüzü mekanizmasıdır. İOS dünyasında yaygın olmasına rağmen, Android ekosisteminde kendini garip hissetmeyen bir UI hilesi. Resmi Twitter uygulamasında kontrol etmenizi şiddetle tavsiye ederim. :)
Thierry-Dimitri Roy

Buradaki yerel davranış, bir listenin sonuna geldiğinizi belirtmektir. Bunu yapmak ve yenileme yapmak, platformun yaptıklarını yapmadığınız için aynı değildir. Bu, kullanıcıyı şaşırtacağınız anlamına gelir. Sadece bir listenin sonuna geldiğim için kesinlikle beklemek ya da bir yenileme istemem. Yenilemek için aşağı çekin çok daha sezgisel ve net. Ve yerli twitter uygulaması kullandığı için, büyük miktarda insanın aşina olduğu bir UI kavramı olduğunu söylemek onun adil olduğunu düşünüyorum.
steprobe



1

En son Lollipop Pull-To Refresh'i almak için:

  1. En yeni Lollipop SDK ve Ekstralar / Android destek kitaplığını indirin
  2. Projenin Oluşturma Hedefini Android 5.0'a ayarlayın (aksi takdirde destek paketinde kaynak hataları olabilir)
  3. Libs / android-support-v4.jar dosyanızı 21'inci sürüme güncelleyin
  4. android.support.v4.widget.SwipeRefreshLayoutArtı kullanınandroid.support.v4.widget.SwipeRefreshLayout.OnRefreshListener

Ayrıntılı kılavuz burada bulunabilir: http://antonioleiva.com/swiperefreshlayout/

Artı ListView canChildScrollUp()için yorumlarda hakkında okumanızı tavsiye ederim ;)


Artı sadece canChildScrollUp () bahsetmek için. Çok önemli!
Petro

1

Yalantis tarafından çok ilginç Pull-to-Refresh . İOS için Gif, ancak kontrol edebilirsiniz :)

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


0

Öncelikle android'de düzeni yenilemek için Pull'un ne olduğunu bilmeliyiz. Android'de yenilemek için çekme-tokatlamak için çekme diyebiliriz. ekranı yukarıdan aşağıya doğru kaydırdığınızda, setOnRefreshListener temel alınarak bazı işlemler yapılır.

Yenilemek için android çekme nasıl uygulanacağını gösteren öğretici İşte . Umarım bu yardımcı olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.