French HorizontalScrollView vs TabHost

zolive33

Active Member
Licensed User
Longtime User
Bonjour à tous,

Je découvre la programmation pour Android est B4A est pour moi un outil formidable. Surtout quand on ne maitrise pas du tout le langage Java!

Mais voilà que je me retrouve complètement bloqué, j'en appelle donc à votre aide.... Et à vos compétences.

Dans une Activité j'ai intégré un objet HorizontalScrollView qui contient plusieurs éléments dont une Scrollview (vertical), et une ListView. Tout fonctionne très bien mise à part le scrolling vertical sur la Scrollview qui semble se bloquer si l'on slide horizontalement. Alors que la ListView fonctionne correctement. Je n'y comprend rien.
Je souhaiterai que la Scrollview se comporte comme la ListView : si l'on slide verticalement, cela bloque le scrolling horizontal jusqu'à ce que l'on relache le tactile. Est-ce possible?

Je pourrais utiliser un TabHost mais il n'intègre pas la gestuelle horizontale (et ne répond pas à mes besoins ergonomiques).

D'avance un grand merci à toutes celles et ceux qui s'interesseront à mon problème.
 

zolive33

Active Member
Licensed User
Longtime User
Bonjour Informatix,

C'est exactement cela. Merci pour l'info, je vais utiliser cette librairie.

A bientôt.
 

zolive33

Active Member
Licensed User
Longtime User
Pour celles ou ceux que cela intéresse voici la classe que j'utilise pour manipuler une Scrollview horizontal. N'hésitez pas à la reprendre et à l'améliorer. Je mettrai un exemple d'utilisation dans le post suivant.

B4X:
'/**************************************************************************/
'/*** Classe : Interface UI - Scrollview Horizontale                     ***/
'/*** VEM    : Prj -> 1.0.0 | obj -> 1.0.0| Date -> 28/09/2012           ***/
'/*** Auteur : Zolive33                                                  ***/
'/*** Modif. :                                                           ***/
'/**************************************************************************/
'/*** Evènement : _SelectChange()                                        ***/
'/**************************************************************************/

Sub Class_Globals
   
   'Données Techniques de la classe
   Private ClassName As String : ClassName="ObjExtHorizontalScrollView"
   Private IsInitOK As Boolean : IsInitOK=False
   
   'Objets interface du selecteur de type d'opération
   Private pnParent As Panel
   Private hsvContainer As HorizontalScrollView
   Private lblTitle As Label
   Private lblTitlePrev As Label
   Private lblTitleNext As Label
   Private iHsvElementWidth As Int 'Largeur d'un élément du scroller
   Private iHsvBlankWith As Int 'Largeur des zones vides avant le 1er Element et après le dernier élément
   Private iDesign As Int
   
   'Eléments du sélecteur hsvContainer
   Private Timer_hsvContainer As Timer
   Private LastPosition_hsvContainer As Int
   Private Velocity_hsvContainer As Int : Velocity_hsvContainer = 1
   Private iCurrentIndex As Int
   
   'Objets utilisés pour la gestion d'évènement
   Private Module As Object
   Private NomEvenement As String
   
   'Option de design
   Public CST_DESIGN_TOP_ARROWS As Int:CST_DESIGN_TOP_ARROWS=1
   Public CST_DESIGN_BOTTOM_ARROWS As Int:CST_DESIGN_BOTTOM_ARROWS=2
   Public CST_DESIGN_DUAL_ARROWS As Int:CST_DESIGN_DUAL_ARROWS=3
   Public CST_DESIGN_TITLE_PANEL As Int:CST_DESIGN_TITLE_PANEL=4
   
End Sub

#Region Initialisation

Public Sub Initialize(pPanel As Panel,pModule As Object, pNomEvenement As String,InternalViewSize As Int,FadingEdgeLength As Int)
'------------------------------------------------
'Procédure d'initialisation du selecteur de type d'opération
'@Param  : une activité (ou un panel), nom du module appelant,un nom pour l'exécution des évènement, taille des vues
'@Retour : N/A
'------------------------------------------------
   
   Try
      'Récupération du panel d'accueil de la scrollview
      pnParent=pPanel
      'récupération du module appelant
      Module = pModule
      'récupération du nom de l'évènement
      NomEvenement = pNomEvenement
      
      'Ajout de la scrollview
      hsvContainer.Initialize(pnParent.Width,"hsvContainer")
      pnParent.AddView(hsvContainer, 0, 0,pnParent.Width,pnParent.Height)
      
      'Largeur des panneaux du sélecteur
      iHsvElementWidth = InternalViewSize
      'Largeur des vides de début et de fin
      iHsvBlankWith = (hsvContainer.Width - iHsvElementWidth)/2
      
      Dim ref As Reflector
      ref.Target = hsvContainer
      'Augmentation de la taille du dégradé
      ref.RunMethod2("setFadingEdgeLength",FadingEdgeLength,"java.lang.int")
      'Déclaration de l'évènement OnTouch pour le scroller
      ref.SetOnTouchListener("hsvContainer_Touch")
      
      'Initialisation du timer
      Timer_hsvContainer.Initialize ("Timer_hsvContainer",1)
      Timer_hsvContainer.Enabled = False
      
      IsInitOK = True
   
   Catch
      
      GApp.GestErreur(ClassName,"Initialize")
   
   End Try
   
End Sub

Public Sub IsInitialized() As Boolean
'------------------------------------------------
'Confirme l'initialisation de l'objet
'@Param  : N/A
'@Retour : vrai si l'objet est initialisé
'------------------------------------------------
   
   Return(IsInitOK)
   
End Sub

#End Region

#Region Ergonomie

Public Sub Design(pDesign As Int)
'------------------------------------------------
'Choix du design
'@Param  : N/A
'@Retour : vrai si l'objet est initialisé
'------------------------------------------------

   Try

      Select pDesign
         Case CST_DESIGN_DUAL_ARROWS
            hsvContainer.Top=5dip
            hsvContainer.Height=pnParent.Height-10dip
            FlecheHaut (pnParent)
            FlecheBas (pnParent)
         Case CST_DESIGN_TOP_ARROWS
            hsvContainer.Top=5dip
            FlecheHaut (pnParent)
         Case CST_DESIGN_BOTTOM_ARROWS
            hsvContainer.Height=pnParent.Height-10dip
            FlecheBas (pnParent)
         Case CST_DESIGN_TITLE_PANEL
            hsvContainer.Top=35dip
            hsvContainer.Height=pnParent.Height-35dip
            lblTitlePrev.Initialize("lblTitlePrev")
            pnParent.AddView(lblTitlePrev,1,1,1,1)
            lblTitlePrev.Height=35dip
            lblTitlePrev.Width=pnParent.Width/3
            lblTitlePrev.Left=0
            lblTitlePrev.Top=0
            lblTitlePrev.TextSize=12
            lblTitlePrev.Color=Colors.Gray
            lblTitlePrev.TextColor=Colors.LightGray
            lblTitlePrev.Typeface = Typeface.DEFAULT 
            lblTitlePrev.Gravity = Gravity.CENTER_HORIZONTAL + Gravity.CENTER_VERTICAL
            lblTitle.Initialize("lblTitle")
            pnParent.AddView(lblTitle,1,1,1,1)
            lblTitle.Height=lblTitlePrev.Height
            lblTitle.Width=lblTitlePrev.Width
            lblTitle.Left=lblTitlePrev.Left+lblTitlePrev.Width
            lblTitle.Top=0
            lblTitle.TextSize=12
            lblTitle.Color=Colors.Gray
            lblTitle.TextColor=Colors.White
            lblTitle.Typeface = Typeface.DEFAULT_BOLD 
            lblTitle.Gravity = Gravity.CENTER_HORIZONTAL + Gravity.CENTER_VERTICAL
            lblTitleNext.Initialize("lblTitleNext")
            pnParent.AddView(lblTitleNext,1,1,1,1)
            lblTitleNext.Height=lblTitle.Height
            lblTitleNext.Width=lblTitle.Width
            lblTitleNext.Left=lblTitle.Left+lblTitle.Width
            lblTitleNext.Top=0
            lblTitleNext.TextSize=12
            lblTitleNext.Color=Colors.Gray
            lblTitleNext.TextColor=Colors.LightGray
            lblTitleNext.Typeface = Typeface.DEFAULT 
            lblTitleNext.Gravity = Gravity.CENTER_HORIZONTAL + Gravity.CENTER_VERTICAL
      End Select
      
   Catch
      
      GApp.GestErreur(ClassName,"Design")
   
   End Try
   
End Sub

Private Sub FlecheHaut (pPanel As Panel)
'Fleche de gauche du selecteur
      Dim imgFleche As ImageView
      
      Try
         
         imgFleche.Initialize("imgFleche")
         imgFleche.Bitmap = LoadBitmap(File.DirAssets, "objSelTypeMvtFlechH.png")
         imgFleche.Gravity=Gravity.FILL
         pPanel.AddView(imgFleche,1,1,1,1)
         imgFleche.Height=20dip
         imgFleche.Width=imgFleche.Height
         imgFleche.Left=(hsvContainer.Width-imgFleche.Width)/2
         imgFleche.Top=hsvContainer.Top - (imgFleche.Height/3)
         
      Catch
      
      GApp.GestErreur(ClassName,"FlecheHaut")
   
   End Try
   
End Sub

Private Sub FlecheBas (pPanel As Panel)
'Fleche de gauche du selecteur
      Dim imgFleche As ImageView
      
      Try
      
         imgFleche.Initialize("imgFleche")
         imgFleche.Bitmap = LoadBitmap(File.DirAssets, "objSelTypeMvtFlechB.png")
         imgFleche.Gravity=Gravity.FILL
         pPanel.AddView(imgFleche,1,1,1,1)
         imgFleche.Height=20dip
         imgFleche.Width=imgFleche.Height
         imgFleche.Left=(hsvContainer.Width-imgFleche.Width)/2
         imgFleche.Top=hsvContainer.Top + hsvContainer.Height - (imgFleche.Height*(2/3))
         
      Catch
      
      GApp.GestErreur(ClassName,"FlecheBas")
   
   End Try
End Sub

#End Region

#Region Evénements

Private Sub hsvContainer_Touch (viewtag As Object, Action As Int, x As Float, Y As Float, motionevent As Object) As Boolean
'------------------------------------------------
'Evènement "touché" du scroller de type de mouvements
'@Param  : Action (=1 si le clique ou touché est relaché)
'@Retour : True si l'évènement est consommé (Non exploité ici)
'------------------------------------------------

   Try

      'Calcul du déplacement en cours
      Velocity_hsvContainer = (Abs(LastPosition_hsvContainer - hsvContainer.ScrollPosition))
      LastPosition_hsvContainer = hsvContainer.ScrollPosition
      Timer_hsvContainer.Enabled = False
      
      'Exécution de la procédure d'ajustement si le touché est relaché
      If (Action = 1) AND Velocity_hsvContainer <= 5 Then
         'Lancement du timer bref pour l'ajustement
         Timer_hsvContainer.Interval = 100
         Timer_hsvContainer.Enabled = True
      Else If (Action = 1) AND Velocity_hsvContainer > 5 Then
         'Lancement du timer long pour l'ajustement
         Timer_hsvContainer.Interval = 750
         Timer_hsvContainer.Enabled = True
      End If
   
   Catch
      
      GApp.GestErreur(ClassName,"hsvContainer_Touch")
   
   End Try
   
End Sub

Private Sub Timer_hsvContainer_Tick
'------------------------------------------------
'Evènement de temporisation d'ajustement du scroller
'@Param  : N/A
'@Retour : N/A
'------------------------------------------------

   Dim tmpLastIndex As Int
   
   Try
      
      'récupération de la dernière sélection
      tmpLastIndex = iCurrentIndex
      
      'Ajustement du scroller
      iCurrentIndex=AdjustScrollIndex
      Timer_hsvContainer.Enabled = False
      
      'Mise à jour du titre du panel sélectionné
      UpdateTitle
      
      'Gestion de l'évènement sur changement de sélection
      If iCurrentIndex <> tmpLastIndex AND _
         SubExists(Module, NomEvenement  & "_SelectChange") Then
         'Lancement de la procédure liée au changement de sélection
         CallSub(Module, NomEvenement  & "_SelectChange")
      End If

   Catch
      
      GApp.GestErreur(ClassName,"Timer_hsvContainer_Tick")
   
   End Try
   
End Sub

Private Sub AdjustScrollIndex () As Int
'------------------------------------------------
'Renvoi l'index du panel sélectionné (si besoin ajuste la roulette)
'@Param  : ajuster la roulette (true,false)
'@Retour : index du panel dans la scrollview
'------------------------------------------------

   Dim tmpval As Float
   
   Try
      
      'lecture de l'indice
      tmpval = (hsvContainer.ScrollPosition )/iHsvElementWidth

      If tmpval<>Round(tmpval) Then
         'Ajustement de la position du scroller
         hsvContainer.ScrollPosition =  Round(tmpval)*iHsvElementWidth
      End If
      
      tmpval = Round(tmpval)

   Catch
      
      GApp.GestErreur(ClassName,"AdjustScrollIndex")
   
   End Try
   
   Return (tmpval)
   
End Sub

Private Sub UpdateTitle()
'------------------------------------------------
'Mise à jour du titre (dépend du panel sélectionné)
'@Param  : N/A
'@Retour : N/A
'------------------------------------------------
   Dim tmpPanel As Panel
   
   Try
   
      If lblTitle.IsInitialized Then
         tmpPanel=hsvContainer.Panel.GetView(iCurrentIndex)
         lblTitle.Text=tmpPanel.Tag
         If iCurrentIndex>0 Then
            tmpPanel=hsvContainer.Panel.GetView(iCurrentIndex-1)
            lblTitlePrev.Text=tmpPanel.Tag
         Else
            lblTitlePrev.Text=""
         End If
         If iCurrentIndex<(hsvContainer.Panel.NumberOfViews-1) Then
            tmpPanel=hsvContainer.Panel.GetView(iCurrentIndex+1)
            lblTitleNext.Text=tmpPanel.Tag
         Else
            lblTitleNext.Text=""
         End If
      End If
   
   Catch
      
      GApp.GestErreur(ClassName,"UpdateTitle")
   
   End Try
   
End Sub

#End Region

Public Sub AddPanel(pTitle As String, pColor As Int) As Panel
'------------------------------------------------
'Procédure d'ajout d'un panel
'@Param  : un panel
'@Retour : N/A
'------------------------------------------------

   Dim iNbrVw As Int
   Dim tmpPanel As Panel
   
   Try
      
      iNbrVw = hsvContainer.Panel.NumberOfViews
      tmpPanel.Initialize("tmpPanel")
      tmpPanel.Tag=pTitle
      tmpPanel.Color=pColor
      hsvContainer.Panel.AddView(tmpPanel, iHsvBlankWith + (iNbrVw*iHsvElementWidth),2dip,iHsvElementWidth,hsvContainer.Height-4dip)
      iNbrVw=iNbrVw+1
      
      'retaillage du panneau = largeur des éléments + zone de début + zone de fin
      hsvContainer.Panel.Width = (iNbrVw*iHsvElementWidth) + (2*iHsvBlankWith)
      
   Catch
      
      GApp.GestErreur(ClassName,"AddPanel")
   
   End Try
   
   Return (tmpPanel)
   
End Sub

Public Sub GetSelectedIndex () As Int
'------------------------------------------------
'Retourne l'index du panel sélectionné
'@Param  : N/A
'@Retour : un type de mouvement
'------------------------------------------------

   Try

      'On attend que le scroller soit stable
      Do While Timer_hsvContainer.Enabled = True
         DoEvents
      Loop
      
   Catch

      GApp.GestErreur(ClassName,"GetSelectedIndex")
   
   End Try

   Return(iCurrentIndex)

End Sub

Public Sub SetIndex (pIndex As Int)
'------------------------------------------------
'Postionne le scroller sur l'index passé en paramètre
'@Param  : un index
'@Retour : N/A
'------------------------------------------------
   Try
      DoEvents
      hsvContainer.ScrollPosition =  (pIndex)*iHsvElementWidth
      Timer_hsvContainer_Tick
      
   Catch

      GApp.GestErreur(ClassName,"SetIndex")
   
   End Try
   
End Sub

Extrait du module GApp (j'ai juste garder l'essentiel pour que ça marche):
B4X:
Sub GestErreur (pModule As String, pProcedure As String)
'------------------------------------------------
'Gestion des Erreurs (Trace et information utilisateur)
'@Param  : Nom du module, nom de la procédure
'@Retour : N/A
'------------------------------------------------

   Dim sTmp As StringBuilder

   sTmp.Initialize
   
   'Traçage de l'anomalie
   sTmp.Initialize
   sTmp.Append("Module : " & pModule).Append(CRLF)
   sTmp.Append("Procédure : " & pProcedure).Append(CRLF)
   sTmp.Append("Erreur : " & LastException.Message ).Append(CRLF)
   
   Log(sTmp)

End Sub
 

Attachments

  • objseltypemvtflechh.png
    objseltypemvtflechh.png
    2.1 KB · Views: 300
  • objseltypemvtflechb.png
    objseltypemvtflechb.png
    2.1 KB · Views: 292
Last edited:

zolive33

Active Member
Licensed User
Longtime User
Voici l'exemple d'utilisation :

B4X:
Sub Globals
   'These global variables will be redeclared each time the activity is created.
   'These variables can only be accessed from this module.
   
   Dim pnTest As Panel 'Créer dans le Designer
   Dim ehsSample As objExtHorizontalScrollView
   
End Sub

B4X:
Sub Activity_Create(FirstTime As Boolean)

   Activity.LoadLayout("Screen_1")
   
   ehsSample.Initialize(pnTest,"Main","ehsSample",pnTest.Width,5dip)
   ehsSample.Design(ehsSample.CST_DESIGN_TITLE_PANEL)
   
   Dim Mypanel_1 As Panel
   Dim lblInfo As Label
   Mypanel_1=ehsSample.AddPanel("Mon titre 1", Colors.Black)
   lblInfo.Initialize("lblInfo")
   Mypanel_1.AddView(lblInfo, 0,5dip,Mypanel_1.Width, 40dip)
   lblInfo.Text="Prochainement..."
   lblInfo.TextColor=Colors.White
   lblInfo.Gravity=Gravity.CENTER_HORIZONTAL
   
   Dim Mypanel_2 As Panel
   Dim lblInfo As Label
   Mypanel_2=ehsSample.AddPanel("Mon titre 2", Colors.Black)
   lblInfo.Initialize("lblInfo")
   Mypanel_2.AddView(lblInfo, 0,5dip,Mypanel_2.Width, 40dip)
   lblInfo.Text="Prochainement..."
   lblInfo.TextColor=Colors.White
   lblInfo.Gravity=Gravity.CENTER_HORIZONTAL
   
   Dim Mypanel_3 As Panel
   Dim lblInfo As Label
   Mypanel_3=ehsSample.AddPanel("Mon titre 3", Colors.Black)
   lblInfo.Initialize("lblInfo")
   Mypanel_3.AddView(lblInfo, 0,5dip,Mypanel_3.Width, 40dip)
   lblInfo.Text="Prochainement..."
   lblInfo.TextColor=Colors.White
   lblInfo.Gravity=Gravity.CENTER_HORIZONTAL
   
   ehsSample.SetIndex(0)
   
End Sub

Sub ehsSample_SelectChange()
   
   ToastMessageShow("Selection : " & ehsSample.GetSelectedIndex, False)
   
End Sub
 
Top