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

Android Discussion :

ScrollView vertical sur plusieurs pages?


Sujet :

Android

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2018
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2018
    Messages : 10
    Par défaut ScrollView vertical sur plusieurs pages?
    Bonjour à tous et à toutes,

    Je suis étudiante en développement Android et je dois me confronter à une difficulté frustrante

    Je dois coder une app affichant:
    • Une page (couleur de fond + une image)
    • Un swipe (de bas en haut)
    • Une page (couleur de fond + une image)
    • Un swipe (de bas en haut ou haut en bas)
    • etc.... (environs 10 fois)

    Mes recherches m'ont amené vers <ScrollView> que j'ai donc utilisé avec un RelativeLayout, mais en vain, mes images sont les unes en dessous des autres et non une par page ou bien elles sont superposées
    Et dans les deux cas = aucun mouvement de swipe... pas d'actions...


    Je sèche, j'ai passé la journée dessus et je perds du temps



    Dois-je me résigner à utiliser un LinearLayout? Le Relative me convient à merveille pour placer les éléments

    Dois-je créer un nouveau fichier XML pour chaque "page"? (ça me semble méga farfelu)

    Le RelativeLayout ne serait pas compatible avec le ScrollView?

    Quelqu'un aurait un ptit bout de code à proposer comme exemple? Car je n'ai aucune idée de comment faire une page pour une image..


    (Je précise que j'ai vérifié la fermeture de toutes les balises etc... les trucs bêtes quoi)

    Merci d'avance


    Bien à vous,

    Akelato

  2. #2
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 693
    Par défaut
    Les pages verticales ca n'existe pas en Android (ca existe nulle part en fait).

    C'est soit un scroll vertical classique comme tu as déjà fait avec une ScrollView , soit des pages latérales avec un ViewPager.

    Après tu va sans doute trouver des librairies qui permette de faire un viewpager vertical mais ergonomiquement c'est ... spécial
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Par défaut
    Salut
    -----

    J'ai déjà utilisé des scrolls verticaux dans certaines applications, comme par exemple naviguer dans une maison (passage d'un étage à l'autre par scroll vertical, et d'une pièce à l'autre en horizontal)
    Si on se limite à un seul sens de déplacement (dans ton cas: vertical) c'est relativement simple.

    Il y a deux étapes:

    La première étape est de transformer visuellement le scroll horizontal en scroll vertical. Pour ça, on utilise un PageTransformer spécifique, dérivé de ViewPager.PageTransformer, et on surcharge sa méthode transformPage()
    Cette méthode fournit deux paramètres: La page concernée et le déplacement relatif fait par le ViewPager, exprimé en largeur d'écran.
    Et donc la page centrée à l'écran a un déplacement de 0, un déplacement de -1 correspond à une page complètement décalée à gauche et de +1 complètement décalée à droite (et donc invisibles)
    La méthode est appelée par le ViewPager pour toutes les pages existantes, visibles ou non, sachant qu'une page qui est totalement visible à l'écran a donc un déplacement de 0, et une vue partiellement visible a un déplacement dans l'intervalle ouvert ]-1,+1[

    On peut déjà, pour éviter de tout calculer, rendre toute vue avec déplacement <=-1 ou >=1 invisible, on ne s'occupe dès lors plus que des vues partiellement visibles (celles en cours de scroll). L'astuce consiste à commencer par contrecarrer le déplacement horizontal par défaut: Vu qu'on reçoit le déplacement relatif, il suffit d'affecter à la page un déplacement inverse dont la valeur en pixel vaut l'inverse du déplacement multiplié par la largeur d'écran. Ainsi, les fragments partiellement visibles sont bloqués horizontalement au centre de l'écran (et donc superposés). Reste ensuite simplement à affecter à chaque page un déplacement vertical qui est le déplacement relatif multiplié par la hauteur d'écran.

    Ça donne quelque chose du style (en Java):


    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
    32
    ///////////////////////////////////////////////////////////////////////////////
    //                            VERTICAL PAGER TRANSFORMER                     //
    ///////////////////////////////////////////////////////////////////////////////
    //-----------------------------------------------------------------------------
    // Le fragment se déplace verticalement au lieu d'horizontalement
    //-----------------------------------------------------------------------------
    public class VerticalPageTransformer implements ViewPager.PageTransformer
    {
    	@Override
    	public void transformPage(View view, float position)
    	{
    		// Fragment hors écran vers la gauche
    		if (position < -1)                                // [-infini,-1[
    		{
    			view.setAlpha(0);
    		}
    		// Fragment dans la zone visible
    		else if (position <= 1)                            // [-1,1]
    		{
    			view.setAlpha(1);                            // visible
    			view.setTranslationX(view.getWidth() * -position); // on bloque le mouvement horizontal
    			float yPosition = position * view.getHeight(); // calcul de la position verticale
    			view.setTranslationY(yPosition);            // on applique la translation verticale
    		}
     
    		// Fragment hors zone visible par la droite
    		else                                                // ]1,infini]
    		{
    			view.setAlpha(0);
    		}
    	}
    }
    Le code est presque plus court que l'explication, mais vu que le but est d'apprendre...

    Quand on a fait ça, on obtient un déplacement visuel vertical à l'écran, mais ce déplacement s'effectue par un glissement du doigt horizontal.

    La seconde étape consiste donc à inverser le mouvement du doigt.
    Et ça, ça se fait de façon aussi simple, en dérivant le ViewPager et en surchargeant les méthodes onInterceptTouchEvent() et onTouchEvent()

    Ces méthodes reçoivent les déplacements du doigt x et y. L'astuce consiste à fournir à la classe parent le déplacement reçu avec inversion de X et de Y. Il faut juste prendre la précaution de recalculer x et y en fonction de la hauteur et la largeur de l'écran: Un déplacement en X sur toute la largeur de l'écran doit correspondre à un déplacement en Y sur toute la hauteur de l'écran. De la sorte, le ViewPager croit que lorsque l'utilisateur déplace son doigt verticalement que ce déplacement est en réalité horizontal

    Et donc, on obtient un truc du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public boolean onInterceptTouchEvent(MotionEvent event)
    	{
    		boolean result = super.onInterceptTouchEvent(swapXY(event)); // inverser x et y
    		swapXY(event);		// On remet à l'endroit pour classes filles
    		return result;		// On retourne résultat
    	}
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	public boolean onTouchEvent(MotionEvent event)
    	{
    		boolean result = super.onTouchEvent(swapXY(event));	// on inverse x et y
    		swapXY(event);
    		return result;
    	}
    Le swap est la simple inversion avec mise à l'échelle:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    	private MotionEvent swapXY(MotionEvent event)
    	{
    		float width = getWidth();						// largeur
    		float height = getHeight();						// hauteur
     
    		float newX = (event.getY() / height) * width;	// x = y remis à l'échelle
    		float newY = (event.getX() / width) * height;	// y = x remis à l'échelle
     
    		event.setLocation(newX, newY);					// appliquer modifs
    		return event;								// retourner event modifié
    	}
    Et voilà un scroll vertical: ça fonctionne aussi pour n'importe quel type de scroll, pour changer les transitions (cube, perspectives etc), et ça permet même (mais il faut un peu plus de code) d'avoir un scroll 2D (horizontal ET vertical)
    On peut faire un peu plus court, mais j'ai conservé l'aspect didactique

    Je te laisse chercher sur la façon d'utiliser un ViewPager et un ViewPagerTransformer, c'est tout sauf compliqué.

    J'espère que ça t'aura aidé

    A+
    Claude

  4. #4
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2018
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2018
    Messages : 10
    Par défaut
    Citation Envoyé par ClaudeBg Voir le message
    Salut
    -----

    J'ai déjà utilisé des scrolls verticaux dans certaines applications, comme par exemple naviguer dans une maison (passage d'un étage à l'autre par scroll vertical, et d'une pièce à l'autre en horizontal)
    Si on se limite à un seul sens de déplacement (dans ton cas: vertical) c'est relativement simple.

    Il y a deux étapes:

    La première étape est de transformer visuellement le scroll horizontal en scroll vertical. Pour ça, on utilise un PageTransformer spécifique, dérivé de ViewPager.PageTransformer, et on surcharge sa méthode transformPage()
    Cette méthode fournit deux paramètres: La page concernée et le déplacement relatif fait par le ViewPager, exprimé en largeur d'écran.
    Et donc la page centrée à l'écran a un déplacement de 0, un déplacement de -1 correspond à une page complètement décalée à gauche et de +1 complètement décalée à droite (et donc invisibles)
    La méthode est appelée par le ViewPager pour toutes les pages existantes, visibles ou non, sachant qu'une page qui est totalement visible à l'écran a donc un déplacement de 0, et une vue partiellement visible a un déplacement dans l'intervalle ouvert ]-1,+1[

    On peut déjà, pour éviter de tout calculer, rendre toute vue avec déplacement <=-1 ou >=1 invisible, on ne s'occupe dès lors plus que des vues partiellement visibles (celles en cours de scroll). L'astuce consiste à commencer par contrecarrer le déplacement horizontal par défaut: Vu qu'on reçoit le déplacement relatif, il suffit d'affecter à la page un déplacement inverse dont la valeur en pixel vaut l'inverse du déplacement multiplié par la largeur d'écran. Ainsi, les fragments partiellement visibles sont bloqués horizontalement au centre de l'écran (et donc superposés). Reste ensuite simplement à affecter à chaque page un déplacement vertical qui est le déplacement relatif multiplié par la hauteur d'écran.

    Ça donne quelque chose du style (en Java):


    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
    32
    ///////////////////////////////////////////////////////////////////////////////
    //                            VERTICAL PAGER TRANSFORMER                     //
    ///////////////////////////////////////////////////////////////////////////////
    //-----------------------------------------------------------------------------
    // Le fragment se déplace verticalement au lieu d'horizontalement
    //-----------------------------------------------------------------------------
    public class VerticalPageTransformer implements ViewPager.PageTransformer
    {
    	@Override
    	public void transformPage(View view, float position)
    	{
    		// Fragment hors écran vers la gauche
    		if (position < -1)                                // [-infini,-1[
    		{
    			view.setAlpha(0);
    		}
    		// Fragment dans la zone visible
    		else if (position <= 1)                            // [-1,1]
    		{
    			view.setAlpha(1);                            // visible
    			view.setTranslationX(view.getWidth() * -position); // on bloque le mouvement horizontal
    			float yPosition = position * view.getHeight(); // calcul de la position verticale
    			view.setTranslationY(yPosition);            // on applique la translation verticale
    		}
     
    		// Fragment hors zone visible par la droite
    		else                                                // ]1,infini]
    		{
    			view.setAlpha(0);
    		}
    	}
    }
    Le code est presque plus court que l'explication, mais vu que le but est d'apprendre...

    Quand on a fait ça, on obtient un déplacement visuel vertical à l'écran, mais ce déplacement s'effectue par un glissement du doigt horizontal.

    La seconde étape consiste donc à inverser le mouvement du doigt.
    Et ça, ça se fait de façon aussi simple, en dérivant le ViewPager et en surchargeant les méthodes onInterceptTouchEvent() et onTouchEvent()

    Ces méthodes reçoivent les déplacements du doigt x et y. L'astuce consiste à fournir à la classe parent le déplacement reçu avec inversion de X et de Y. Il faut juste prendre la précaution de recalculer x et y en fonction de la hauteur et la largeur de l'écran: Un déplacement en X sur toute la largeur de l'écran doit correspondre à un déplacement en Y sur toute la hauteur de l'écran. De la sorte, le ViewPager croit que lorsque l'utilisateur déplace son doigt verticalement que ce déplacement est en réalité horizontal

    Et donc, on obtient un truc du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public boolean onInterceptTouchEvent(MotionEvent event)
    	{
    		boolean result = super.onInterceptTouchEvent(swapXY(event)); // inverser x et y
    		swapXY(event);		// On remet à l'endroit pour classes filles
    		return result;		// On retourne résultat
    	}
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	public boolean onTouchEvent(MotionEvent event)
    	{
    		boolean result = super.onTouchEvent(swapXY(event));	// on inverse x et y
    		swapXY(event);
    		return result;
    	}
    Le swap est la simple inversion avec mise à l'échelle:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    	private MotionEvent swapXY(MotionEvent event)
    	{
    		float width = getWidth();						// largeur
    		float height = getHeight();						// hauteur
     
    		float newX = (event.getY() / height) * width;	// x = y remis à l'échelle
    		float newY = (event.getX() / width) * height;	// y = x remis à l'échelle
     
    		event.setLocation(newX, newY);					// appliquer modifs
    		return event;								// retourner event modifié
    	}
    Et voilà un scroll vertical: ça fonctionne aussi pour n'importe quel type de scroll, pour changer les transitions (cube, perspectives etc), et ça permet même (mais il faut un peu plus de code) d'avoir un scroll 2D (horizontal ET vertical)
    On peut faire un peu plus court, mais j'ai conservé l'aspect didactique

    Je te laisse chercher sur la façon d'utiliser un ViewPager et un ViewPagerTransformer, c'est tout sauf compliqué.

    J'espère que ça t'aura aidé

    A+
    Claude

    MERCI BEAUCOUUUP !

    C'est gentil d'avoir pris le temps de rédiger tout ça ! Je vais tester tout ça et faire mes petites recherches.

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

Discussions similaires

  1. [CR] probleme de somme sur plusieurs pages
    Par d@rthwing dans le forum SAP Crystal Reports
    Réponses: 9
    Dernier message: 26/08/2005, 14h31
  2. [Struts]Affiche d'une liste sur plusieurs pages
    Par guillaume_85 dans le forum Struts 1
    Réponses: 3
    Dernier message: 24/06/2005, 20h23
  3. [CR?] Tableaux sur plusieurs pages
    Par Nout dans le forum SAP Crystal Reports
    Réponses: 3
    Dernier message: 18/05/2005, 14h58
  4. [JSP] affichage de resultat sur plusieurs pages
    Par de LANFRANCHI dans le forum Servlets/JSP
    Réponses: 13
    Dernier message: 10/02/2005, 10h00
  5. [CR8] Problème tableau sur plusieurs pages???
    Par christophe28 dans le forum SAP Crystal Reports
    Réponses: 5
    Dernier message: 02/11/2004, 15h46

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