web-dev-qa-db-fra.com

Comment implémenter Android Pull-to-Refresh

Dans Android applications telles que Twitter (application officielle), lorsque vous rencontrez un ListView, vous pouvez le dérouler (il rebondira dès sa publication) pour actualiser le contenu.

Je me demande quelle est la meilleure façon, à votre avis, de mettre cela en œuvre.

Quelques possibilités auxquelles je pouvais penser:

  1. Un élément au-dessus de la liste - Cependant, je ne pense pas que revenir à la position 1 (basé sur 0) avec une animation sur la liste est une tâche facile.
  2. Une autre vue en dehors de ListView - mais je dois prendre soin de déplacer la position de la ListView vers le bas quand elle est tirée, et je ne suis pas sûr de savoir si nous pouvons détecter si les touches de déplacement vers la ListView font toujours vraiment défiler les éléments de la ListView.

Des recommandations?

P.S. Je me demande quand le code source de l'application Twitter officielle sera publié. Il a été mentionné que le document serait publié, mais six mois se sont écoulés et nous n'en avons pas entendu parler depuis.

405

Enfin, Google a publié une version officielle de la bibliothèque à extraire!

Elle s’appelle SwipeRefreshLayout, à l’intérieur de la bibliothèque de support, et la documentation est ici :

  1. Ajoutez SwipeRefreshLayout en tant que parent de la vue qui sera traité comme une extraction pour actualiser la présentation. (J'ai pris ListView comme exemple, cela peut être n'importe quel View comme LinearLayout, ScrollView etc.)

    <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. Ajouter un auditeur à votre classe

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

Vous pouvez également appeler pullToRefresh.setRefreshing(true/false); selon vos besoins.

266

J'ai tenté d'implémenter un composant d'extraction pour actualiser, il est loin d'être terminé , mais il présente une implémentation possible, https: // github.com/johannilsson/Android-pulltorefresh .

La logique principale est implémentée dans PullToRefreshListView qui étend ListViewEn interne, il contrôle le défilement d'une vue d'en-tête à l'aide de smoothScrollBy (API de niveau 8). Le widget est maintenant mis à jour avec la prise en charge de la version 1.5 ou ultérieure. Veuillez lire le README pour la prise en charge de la version 1.5.

Dans vos mises en page, vous l'ajoutez simplement comme ceci.

<com.markupartist.Android.widget.PullToRefreshListView
    Android:id="@+id/Android:list"
    Android:layout_height="fill_parent"
    Android:layout_width="fill_parent"
    />
79
Johan Berg Nilsson

J'ai également mis en place une bibliothèque PullToRefresh robuste, à code source ouvert, facile à utiliser et hautement personnalisable pour Android. Vous pouvez remplacer votre ListView par PullToRefreshListView comme décrit dans la documentation de la page du projet.

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

54
Erik

Le moyen le plus simple, selon moi, est fourni par la bibliothèque de support Android:

Android.support.v4.widget.SwipeRefreshLayout;

une fois importé, vous pouvez définir votre mise en page comme suit:

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

Je suppose que vous utilisez la vue recycleur au lieu de listview. Toutefois, listview fonctionne toujours, il vous suffit donc de remplacer recyclerview par listview et de mettre à jour les références dans le code Java (fragment).

Dans votre fragment d'activité, vous implémentez d'abord l'interface, 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);

   }
}

Espérons que cela aide les masses

38
larrytech

Dans ce lien, vous pouvez trouver un fork de la célèbre vue PullToRefresh avec de nouvelles implémentations intéressantes comme PullTorRefreshWebView ou PullToRefreshGridView ou la possibilité d’ajouter un PullToRefresh sur le bord inférieur. d'une liste.

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

Et le meilleur est que le travail est parfait dans Android 4.1 (la normale PullToRefresh ne fonctionne pas)

21
Aracem

Pour implémenter Android Pull-to-Refresh, essayez ce morceau de code,

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

Classe d'activité:

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
mani

J'ai le moyen très facile de faire ceci mais maintenant c'est sûr la manière infaillible Il y a mon code 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;
    }
}

Vous devez juste implémenter ListViewTouchEventListener sur votre activité pour laquelle vous voulez utiliser ce ListView et définir l'écouteur.

Je l'ai implémenté dans 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");
    }
}

Ça marche pour moi :)

18
Pushpan

Personne n'a mentionné le nouveau type de "tirer pour actualiser" qui apparaît en haut de la barre d'action, comme dans l'application Google Now ou Gmail.

Il existe une bibliothèque ActionBar-PullToRefresh qui fonctionne exactement de la même manière.

9
tomrozb

Notez qu'il existe des problèmes UX à résoudre lors de l'implémentation sur Android et WP.

"Un bon indicateur des raisons pour lesquelles les concepteurs/développeurs ne devraient pas implémenter l'extraction par extraction dans le style des applications iOS est la façon dont Google et leurs équipes n'utilisent jamais l'extraction par actualisation sur Android tant qu'ils l'utilisent dans iOS. "

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

7
uobroin

Si vous ne souhaitez pas que votre programme ressemble à un programme iPhone intégré à Android, essayez de le rendre plus naturel et de faire quelque chose de similaire à Gingerbread:

alt text

4
Lie Ryan

J'ai écrit un pull pour actualiser le composant ici: https://github.com/guillep/PullToRefresh Il fonctionne bien si la liste ne contient pas d'éléments et je l'ai testé sur> = 1.6. Android téléphones.

Toute suggestion ou amélioration est appréciée :)

4
Guille Polito

Je pense que la meilleure bibliothèque est: https://github.com/chrisbanes/Android-PullToRefresh .

Marche avec:

ListView
ExpandableListView
GridView
WebView
ScrollView
HorizontalScrollView
ViewPager
2
Jossy Paul

Pour obtenir le dernier extrait de Lollipop Pull-To Refresh:

  1. Téléchargez la dernière bibliothèque de support Lollipop SDK and Extras/Android
  2. Définissez la cible de construction du projet sur Android 5.0 (sinon, le package de support technique peut contenir des erreurs avec les ressources)
  3. Mettez à jour votre libs/Android-support-v4.jar à la 21ème version
  4. Utiliser Android.support.v4.widget.SwipeRefreshLayout plus Android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener

Guide détaillé peut être trouvé ici: http://antonioleiva.com/swiperefreshlayout/

Plus pour ListView, je recommande de lire sur canChildScrollUp() dans les commentaires;)

1
goRGon

Très intéressant Pull-to-Refresh par Yalantis . Gif pour iOS, mais vous pouvez le vérifier :)

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