Spanish (SOLUC)Teniendo varias copias de un layout en pantalla ¿Puedo acceder a sus elementos por su nombre?

Seneca

Active Member
Licensed User
Hola.

Espero que el título haga una idea de la necesidad que tengo.

Cargo en pantalla varias copias de un Layout. Este Layout lo que tiene es un panel, que a su vez contiene varias Etiquetas, las cuales han de ser rellenadas posteriormente de forma dinámica.

Parto de que para poder acceder a los distintos Paneles con posterioridad los guardo en un List, de donde puedo recuperarlos cuando me sea necesario. Mi duda es cómo puedo acceder a cada Label de cada una de las copias del Layout usando el nombre de cada uno de esos Label, y no tener que recurrir a algo así como:

B4X:
Dim Label1 as Label = panel.GetView(2)

Saludos.
 

Descartex

Well-Known Member
Licensed User
Longtime User

Seneca

Active Member
Licensed User
Muy buenas.
Como ya comenté en este hilo
https://www.b4x.com/android/forum/threads/solucionado-saber-que-componente-tenía-el-foco-previamente-a-la-pulsación-de-un-botón.93484/#post-591668
El nombre NO forma parte de las propiedades accesibles y, según @Erel, no va a formar parte.
En ese mismo hilo, tienes una solución para saber que control has accedido.

Un saludo.

Ya había leído este hilo y aunque la consulta no es igual que la mía, es parecida.

He creado un ejemplo para explicar mi duda. En el ejemplo he cargado en pantalla 4 copias de un panel que contiene a su vez 4 etiquetas. Luego tenemos un Editbox y cuatro botones. Cada botón estará relacionado con cada una de las 4 etiquetas.

La idea es seleccionar como activo una de los 4 paneles, luego escribir algo en el Editbox y posteriormente pulsar uno de los 4 botones. Ahora, el contenido del Editbox debería ser publicado en la etiqueta correspondiente al botón pulsado, en el Panel que previamente se había marcado como activo.

captura.png


B4X:
Sub Globals
    Private pnlContenedor, pnlHijo As Panel
    Private lblCiudad, lblApellidos, lblDomicilio, lblNombre As Label
  
    Private panelactivo As Panel
    Private EditText1 As EditText
End Sub

Sub Activity_Create(FirstTime As Boolean)
    panelactivo.Initialize("")
    Activity.LoadLayout("Principal")
    For n = 0 To 3 'Carga 4 instancias de un mismo layout
        pnlContenedor.LoadLayout ("panel_labels")
        pnlHijo.SetLayout (10dip, 10 + n * 110dip, pnlHijo.Width, pnlHijo.Height)
    Next
End Sub

Sub pnlHijo_Click
    panelactivo.Color = Colors.ARGB(255,156,0,0)
    panelactivo = Sender
    panelactivo.Color = Colors.Green
End Sub

Sub boton_Click
    If panelactivo.NumberOfViews = 0 Then
        'Salta si no se ha seleccionado un Panel Activo
        ToastMessageShow ("Seleccione un panel", False)
        Return
    End If
    Dim boton As Button
    boton.Initialize("")
    boton = Sender
    Dim etiqueta As Label
    etiqueta.Initialize ("")
  
    Select Case boton.Tag
        Case "N"
            etiqueta = panelactivo.GetView (0)
        Case "A"
            etiqueta = panelactivo.GetView (1)
        Case "D"
            etiqueta = panelactivo.GetView (2)
        Case "C"
            etiqueta = panelactivo.GetView (3)
    End Select
    etiqueta.Text = EditText1.Text
End Sub

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

La duda que planteo en este hilo es si puedo recuperar el uso de las etiquetas a través de su nombre en vez de tener que hacerlo con un .GetView(x) de la siguiente manera:

B4X:
    Select Case boton.Tag
        Case "N"
            etiqueta = panelactivo.GetView (0)
        Case "A"
            etiqueta = panelactivo.GetView (1)
        Case "D"
            etiqueta = panelactivo.GetView (2)
        Case "C"
            etiqueta = panelactivo.GetView (3)
    End Select
    etiqueta.Text = EditText1.Text

Por la información que me has dado @Descartex, creo que esta es la forma correcta de hacerlo, ¿no es así?

No tengo problema por hacerlo de esta manera, pero para el caso de que el número de etiquetas fuese grande (en vez de 4), poder usar los nombres de los controles en vez de .GetView(x) sería más intuitivo.

Sé que el código anterior podría reducirse a lo siguiente, teniendo en este caso que poner en los Tag de los botones los números del 0 al 3.

B4X:
    etiqueta = panelactivo.GetView (boton.Tag)
    etiqueta.Text = EditText1.Text

Gracias por la ayuda @Descartex .
 

Attachments

  • varias_instancias_layout.zip
    10.9 KB · Views: 319
Last edited:

Descartex

Well-Known Member
Licensed User
Longtime User
Muy buenas.
Lo que tu necesitas lo he implementado en varias ocasiones ya.
Yo lo he resuelto de la siguiente forma ( seguro que hay varias, pero a mi me funciona ;) ):
Declaras una variable de tipo panel que contendrá el panel "destino" de la accion:
B4X:
Dim PanelDestino as Panel
En el evento Click de los paneles, le asigno el destino:
B4X:
Sub Paneles_Click
   PanelDestino = Sender
End Sub
En el evento Click del Botón, hago lo que debo:
B4X:
Sub Boton_Click
   Dim btn as Button = Sender
   For Each v as View in PanelDestino.GetAllViewsRecursive
       If v is Label Then
          Dim lbl as Label = v
          If btn.Tag = lbl.Tag Then lbl.Text = EditText.Text
       End If
   Next
End Sub
Para ello necesito, que el Tag de los botones de abajo y los Tag de las etiquetas de cada panel sean iguales.
Si necesitas almacenar más info en los Tag (para posteriores procesos) puedes plantearte crear un map de valores y acceder a ellos.

Un saludo.
 

Seneca

Active Member
Licensed User
Hola.

Este método que me aportas es parecido al que yo indicaba, con la ventaja en tu caso de que no he de tener en cuenta el orden de los Labels para poder recuperarlos correctamente mediante .GetView(x)

Es una pena que no haya una manera más directa, sin tener que recurrir a .Tag.

Gracias por el aporte.
 
Top