Spanish [SOLUCIONADO] Dudas sobre la clase ExpandablePanels

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Tomky:

¿Cómo es que no funciona bien en otra activity que no sea main?
Si que funciona bien, lo unico que tienes que pasarle el nombre del activity desde donde lo llamas y en el global definirlo.

B4X:
Sub Globals
  Dim NombrePanel As expandablePanel
 ' .............
 ' .............
 ' .............

  expPnls(i).Initialize("NombreEvento" , "NombreDelOtroActivity" )

¿Cómo hacer scroll automático y preciso con sus paneles, para que al desplegar uno quede centrado en la pantalla?

AltoPanel = (AlturaActivity-AlturaPanel)/2

Saludos
 

tomky

Active Member
Licensed User
Hola bgsoft.
Quizás me haya explicado mal. El código no está en la activity Main.

Y no entendemos cómo aplicar tu código para centrar el panel expandido.
Y más habiendo un scroll de por medio.

Gracias.
 
Last edited:

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola tomky

Quizás me haya explicado mal. El código no está en la activity Main.
Entendí que si quieres hacer lo mismo desde otro activity que no sea el MAIN no te llega a funcionar, por este comentario:
¿Cómo es que no funciona bien en otra activity que no sea main?
Por eso te dije que lo habia probado desde otro activity que no era el MAIN y si que funcionaba. Te referias a eso?

Y no entendemos cómo aplicar tu código para centrar el panel expandido.
Y más habiendo un scroll de por medio.

Si miras el codigo en el Scroll se incrustan los paneles, puedes centrarlo asi una vez acabada la carga:

B4X:
sv.top = (100%y- sv.Panel.Height)/2

Saludos
 

tomky

Active Member
Licensed User
Hola bgsoft.
Tenías razón con la manera de utilizar el código en otra activity.

Pero tu fórmula
B4X:
sv.top = (100%y- sv.Panel.Height)/2

recorta el scrollview.

Te lo escribo todo:

B4X:
Sub Globals

    Dim expPnls(9) As expandablePanel
    Dim pnls(9) As Panel

    Dim sv As ScrollView

    Dim limit

End Sub

Sub Activity_Create(FirstTime As Boolean)

    limit = 8

    Activity.Color = Colors.RGB(232,232,232)

    sv.Initialize(100%y)
    Activity.AddView(sv,0,0,100%x,100%y)
    sv.Color = Colors.Transparent

    Dim Top As Int = 0
    For i = 0 To 8
        ' Initialize with the event name (not sure how to combine the events in to one)
        expPnls(i).Initialize("expPnls" , "OtraActivity")
        ' Get a reference to the panel
        pnls(i) = expPnls(i).AsPanel
        sv.Panel.AddView(pnls(i),10dip,Top,100%x-20dip,300dip)
        Top = Top + 300dip + 10dip
        pnls(i).Color = Colors.RGB(Rnd(0,255),    Rnd(0,255), Rnd(0,255))
        ' Set up parameters for the expandable panels
        expPnls(i).setSpeed(300)
        expPnls(i).maxHeight = 300dip
        expPnls(i).minHeight = 80dip
        ' Collapse the panel
        expPnls(i).Collapse
    Next

End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub expPnls_Click(MyExpPnl As expandablePanel)

        For i = 0 To limit
       
            If expPnls(i).IsExpanded Then
                expPnls(i).Collapse
            End If
        Next
   
            Log("Top Panel Seleccionado = "&MyExpPnl.AsPanel.Top)    'Muestra la posición top actual del panel seleccionado
            Log("ScrollPosition = "&sv.ScrollPosition)
            Log("Activity Height = "&Activity.Height)
            Log("ScrollView Height = "&sv.Height)
            Log("ScrollView Panel Height = "&sv.Panel.Height)
            Log("---")

        MyExpPnl.ToggleHeight
End Sub

'This is the more important part of the sample
'It will move the surrounding views when it is expanded and collapses
'It is imperative to use the same sub name : "eventname & Resize_Views"
Sub expPnls_Resize_Views
    For i = 0 To pnls.Length-1 -1
        pnls(i+1).Top = pnls(i).Top+pnls(i).Height + 10dip
    Next
    sv.Panel.Height = pnls(pnls.Length-1).Top + pnls(pnls.Length-1).Height

    sv.Top = (100%y - sv.Panel.Height) / 2   'Tu código
End Sub

Gracias.
 
Last edited:

dar2o3

Active Member
Licensed User
Longtime User
Ese código tal y como lo tienes puesto no puede compilar.
B4X:
Dim limit
Eso da error, tienes que definir la variable en este caso como int

B4X:
expPnls(i).setSpeed(300)

Aquí te falta un parámetro y también te dará error, tendría que ser algo así como
B4X:
expPnls(i).setSpeed(300,350)

Creo entender que lo que buscas es algo así:

B4X:
sv.ScrollPosition=MyExpPnl.AsPanel.Top

esto debería ir aquí:

B4X:
Sub expPnls_Click(MyExpPnl As Expandablepanel)

        For i = 0 To limit
            If expPnls(i).IsExpanded Then
                expPnls(i).Collapse
            End If
        Next

            Log("Top Panel Seleccionado = "&MyExpPnl.AsPanel.Top)    'Muestra la posición top actual del panel seleccionado
            Log("ScrollPosition = "&sv.ScrollPosition)
            Log("Activity Height = "&Activity.Height)
            Log("ScrollView Height = "&sv.Height)
            Log("ScrollView Panel Height = "&sv.Panel.Height)
            Log("---")

        MyExpPnl.ToggleHeight
 
 
        'Aquí
        sv.ScrollPosition=MyExpPnl.AsPanel.Top
End Sub

Así lograrás mover el ScrollView hasta la posición del expandablepanel pulsado.

Te faltan mas cosas, como en el activity create, despues del for deberías ajustar la altura del panel del scrollview, algo así:

B4X:
sv.Panel.Height=Top

y mas cosicas, pero ya vamos viendo...

P.D. nunca había trabajado antes con esta clase, te recomiendo la lectura de su código para comprender mejor como trabaja, además de que esta clase nos enseña unos cuantos trucos (al menos a mí).
 
Last edited:

bgsoft

Well-Known Member
Licensed User
Longtime User
sv.top = (100%y- sv.Panel.Height)/2
recorta el scrollview.

Perdona, te puse la altura del panel interior del Scroll en vez de la del scroll :oops: , cambialo por esto:



B4X:
sv.top = (100%y- sv.Height)/2

Saludos
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Te faltan mas cosas, como en el activity create, despues del for deberías ajustar la altura del panel del scrollview, algo así:
Code:
sv.Panel.Height=Top

Eso ya se hace después del bucle :

B4X:
sv.Panel.Height = pnls(pnls.Length-1).Top + pnls(pnls.Length-1).Height

Saludos
 
Last edited:

dar2o3

Active Member
Licensed User
Longtime User
Buenos días.
Tienes razón en el evento expPnls_Resize_Views, no lo había visto. :D

Me a gustado esta clase, voy a usarla en una app para mostrar los resultados de una consulta a un servidor, en la que tengo que mostrar bastante información, de esa manera, solo muestro "la cabecera" de los resultados y si al usuario le interesa la información, que se muestre toda al pulsar sobre el expandablepanel, o se os ocurre alguna idea mejor?
 
Last edited:

bgsoft

Well-Known Member
Licensed User
Longtime User

tomky

Active Member
Licensed User
Hola dar2o3 y bgsoft.

dar2o3, tenías razón en que me faltaba el As Int tras el Dim limit.

Pero el expPnls(i).setSpeed(300) solamente admite un parámetro.

La instrucción sv.ScrollPosition=MyExpPnl.AsPanel.Top ya la había probado y no funciona. Solamente medio hace algo, curiosamente al colapsar ese panel.

Y sv.Panel.Height=Top no veo que haga nada.

También queremos uilizar como tú esta clase para mostrar los resultados de una consulta a una base de datos alojada en un servidor. Sí, queda bien chulo.



bgsoft, la instrucción sv.top = (100%y- sv.Height)/2 tampoco hace lo que pido, que se centre siempre el panel expandido en la pantalla. Y además, sv.top muestra que siempre es cero, antes y después de esa asignación.

Gracias a los dos.
 
Last edited:

dar2o3

Active Member
Licensed User
Longtime User
Ayer a la noche hice un proyecto de prueba, a mi si me funcionaba todo lo que e puesto, a ver si esta noche tengo un rato y lo miro bien.
 

dar2o3

Active Member
Licensed User
Longtime User
Buenas noches.

Bueno, en la segunda versión ya veo que expPnls(i).setSpeed(300) solo necesita un parámetro, esto es algo que ha cambiado con respecto a la primera versión, porque ya no usa un timer para crear la animación, ahora usa la librería NineOldsAndroid de @Informatix, esto, nos crea un pequeño problema a la hora de centrar el panel que pulsamos en el ScrollView, porque resulta, que tenemos que esperar a que termine la animación para poder recoger los valores del expPnls pulsado, para resolver esto, creamos un timer que hay que inicializar a un tiempo superior al que pongamos en expPnls(i).setSpeed, para dar tiempo a que termine la animación.

Bueno, te dejo el proyecto de ejemplo con lo que he echo hasta ahora, el primer expPnls y el último no se van a centrar (a ver si averiguas el por que, jejeje) ese "problemilla" lo dejo para que lo soluciones tu, al final me ha llevado mas tiempo del que esperaba :eek:, menos mal que mañana no tengo que madrugar. :D
 

Attachments

  • ExpandablePanelsSample.zip
    466.6 KB · Views: 358
Last edited:

bgsoft

Well-Known Member
Licensed User
Longtime User
La instrucción sv.ScrollPosition=MyExpPnl.AsPanel.Top ya la había probado y no funciona. Solamente medio hace algo, curiosamente al colapsar ese panel.

Aunque te parezca una tonteria, haz esto, a mi cuando me ha fallado el posicionar lo he echo y me funciona.
B4X:
  ' lo llamo dos veces :D
  sv.ScrollPosition=MyExpPnl.AsPanel.Top
  Doevents
  sv.ScrollPosition=MyExpPnl.AsPanel.Top
Verifica primero el valor de MyExpPnl.AsPanel.Top, igual está a 0 y por eso no hace nada, cuenta que le estas diciendo que el scroll se ponga en el top del panel.

Puedes hacer una cosa para verificar en que posición está el scroll:
Cambia la inicialización esta:
B4X:
sv.Initialize(100%y)
Por esta:
B4X:
sv.Initialize2(100%y,"EventoScroll")

Crea este sub donde podras ver donde se va posicionando el scroll:
B4X:
Sub EventoScroll_ScrollChanged(Position As Int)
   log("Posicion scroll " & Position)
End Sub

Con este código tendras mas pistas del posicionamento del scroll, cuando ya te funcione quita el log que come mucho recurso, ya que ahí estará escribiendo muy a menudo.

bgsoft, la instrucción sv.top = (100%y- sv.Height)/2 tampoco hace lo que pido, que se centre siempre el panel expandido en la pantalla. Y además, sv.top muestra que siempre es cero, antes y después de esa asignación.
A ver, esa instrución es simple, se resta el alto de la pantalla del alto del scroll y se divide por dos, de esta forma está en el centro, si no lo está es por que sv.Height es mayor que 100%y (el alto de la pantalla). Pon Log del alto del scroll y de la pantalla y veras los resultados.

Te aconsejo que para depurar emplees el debug, podrá poner puntos de ruptura y mirar valores de objetos o variables, tambien podras cambiar y seguir probando

Saludos
 

tomky

Active Member
Licensed User
Probé el trabajo de dar2o3 y funciona!!
Benditos roedores!! ;)

Lo único que cambié de él es que moví la instrucción del ScrollPosition a dentro de la condición IsExpanded, para que solamente me centre el panel escogido cuando esté expandido.
B4X:
Sub recolocarpanel
    Dim tope As Int
    Dim alturapanel As Int
    For i = 0 To expPnls.Length-1
        If expPnls(i).IsExpanded=True Then
            tope=expPnls(i).AsPanel.Top
            alturapanel=expPnls(i).AsPanel.Height
       
            sv.ScrollPosition=(tope * (50%y)/ (100%y/2)) - (alturapanel/2)
        End If
    Next
End Sub
Y bajé el tiempo de animación a 100, y el del timer a 250.

Muchas gracias a los 2!!
 
Last edited:

dar2o3

Active Member
Licensed User
Longtime User
Me alegro mucho, si pudieras editar el título y poner solucionado sería fantástico.
 

tomky

Active Member
Licensed User
Por si alguno quiere utilizar este ejemplo, al cargarle datos de una base de datos, he tenido que cambiar la línea
B4X:
sv.top = (100%y- sv.Height)/2
por la línea
B4X:
sv.ScrollPosition=expPnls(i).AsPanel.Top
al dejarme de funcionar. No sé por qué.
Ahora no centra el panel, pero lo pone en el borde superior de la pantalla.
 
Top