IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants graphiques Android Discussion :

Listview && onScroll() method


Sujet :

Composants graphiques Android

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    172
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Octobre 2012
    Messages : 172
    Points : 70
    Points
    70
    Par défaut Listview && onScroll() method
    Bonjour à tous,

    J'ai un soucis avec le OnScrollListener et la methode onScroll en particulier...

    mon but:
    - une listview est filled avec un WebService "paginé"
    - il me faut donc une fois arrivé en bas de la liste relancé l'appel WS pour charger la page suivante..

    mon soucis:
    - dans la methode onScroll je fais un test pour savoir si le last element est visible
    - mais plusieurs event me sont remontés :s
    resultat l'index passé au WS (le numero de page) est incrémenté plusieurs fois au lieu d'une seule et me fait donc "sauter" des pages...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    @Override
    public void onScroll(AbsListView lw, final int firstVisibleItem,
                     final int visibleItemCount, final int totalItemCount) {
     
                final int lastItem = firstVisibleItem + visibleItemCount;
                if(lastItem == totalItemCount) {
                    // Last item is fully visible.
                    log("index", index++);
                }
    }
    Avec ce code j'obtiens une trace semblable:
    index 1
    index 2
    index 3
    Ce qui correspond à autant d'appels WS...
    Je voudrais avoir un seul event pour pouvoir faire:
    1 appel, 1 scroll jusqu'en bas, 1 appel, un scroll jusqu'en bas....

    Et ainsi de suite...
    Auriez vous une solution?

    D'avance merci

  2. #2
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    La solution est de créer un item "spécial", placé en fin de liste.

    Quand cet item est visible (onScroll) lancer une tâche asynchrone pour rajouter des éléments à la liste, ce qui décalera le truc etc...
    C'est fait uniquement au niveau de l'Adapter.

    Pas besoin du "onScroll"... il suffit que le getView() soit appelé sur cet item pour qu'on puisse lancer la tâche.

    En plus une jolie animation (progress) permet d'indiquer à l'utilisateur qu'on charge des trucs.
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  3. #3
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    172
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Octobre 2012
    Messages : 172
    Points : 70
    Points
    70
    Par défaut
    Ok jpense voir ce que tu veux dire (ca me fait penser a la lib "AmazingListView"?)

    je vais tester cela...

    Si je comprends bien :
    - dans l'adapter:
    - dans le getView() si position=itemList.length() >> lancer l'appel WS

    et dans le onResponse:
    - listData.addall(dataNextPage)
    - notifyDataSetChanged()

    Merci pour l'idée ^^
    Ps: c'est ce qui est utilisé dans l'appli GMail je crois non?

  4. #4
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Oui

    Ne pas oublier de modifier le item-count de l'adapter (pour qu'il renvoit un item de plus).
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  5. #5
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    172
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Octobre 2012
    Messages : 172
    Points : 70
    Points
    70
    Par défaut
    Merci pour l'astuce

  6. #6
    Membre régulier
    Homme Profil pro
    Inscrit en
    Octobre 2012
    Messages
    172
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Octobre 2012
    Messages : 172
    Points : 70
    Points
    70
    Par défaut
    Juste pour avoir un avis:

    > plutôt que de faire une cellule spec avec loader etc... ET comme tout ce dont j'ai besoin pour réaliser l'appel WS paginé se trouve être dans le "hosting fragment", voila ce que j'ai fait :

    J'ai utilisé le LocalBroadcastManager :

    - dans lAdapter de la liste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    @Override
    	public View getView(int position, View convertView, ViewGroup parent) {
    		
    		Holder holder = null;
    		if (convertView == null) {
    			convertView = mInflater.inflate(R.layout.item_listview_annonces, null);
    			[ ... ]
    			convertView.setTag(holder);
    		} else {
    			holder = (Holder) convertView.getTag();
    		}
    		
    		// gestion pagination du WS :
    		if (position == mItems.size() -1) {
    			// send broadcast message to hosting fragment
    			sendMessage();
    		}
    		
    		return convertView;
    	}
    	
    	/**
    	 * Send an Intent with an action named "my-event". 
    	 */
    	private void sendMessage() {
    	  Intent intent = new Intent("DL-next-page-event");
    	  // add data
    	  intent.putExtra("message", "> charger la page suivante via WS");
    	  LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
    	}
    puis dans le hosting fragment :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
            /** 
             * handler for received Intents for the "DL-next-page-event" event 
             */
    	private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
    		@Override
    		public void onReceive(Context context, Intent intent) {
     
    	            // Extract data included in the Intent
    		    String message = intent.getStringExtra("message");
    		    LogUtils.LOGI("RECEIVER", "Got message: " + message);
     
    		    // appel WS de la pages d'annonces suivante
    		    if (mList.size() < mItemsNumber) {
    			mProgressLayout.setVisibility(View.VISIBLE);
    	    		DataManager.getInstance(getActivity()).getAddManager()
    	    			.searchForAddsWith(<item1>, <item2>, mIndexPagination);
    	    		LogUtils.LOGI("index loaded", "> page n°"+mIndexPagination);
    		    }
    		}
    	};
    je send donc un broadcast auquel j'abonne mon "hosting fragment" qui, a la reception se chargera de faire tout le boulot (y compris la loading view qui du coup s'etendra sur tout l'ecran : je trouve ca mieux car on empeche ainsi l'utilisateur de cliquer sur une cellule de la liste ce qui aurait pour effet de creer un nouveau fragment et serait donc, par la même occasion, susceptible de causer un crash en retour WS since le fragment de la liste serait passer en pause et la vue serait donc devenue inaccéssible)

    La tout de suite ca me semble être la meilleure facon de proceder et je compte m'y prendre de la même maniere à l'avenir...

    Qu'en pensez vous d'un point de vue conceptuel?

+ Répondre à la discussion
Cette discussion est résolue.

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo