Spanish ¿Es manera correcta de cargar múltiples copias de un layout y posterior modificación mediante códig?

Seneca

Active Member
Licensed User
Hola.

Quiero publicar en un ScrolView una serie de informaciones (noticias) que tengo alojadas en una base de datos. Cada noticia se compone de un Título y un Texto.

Para ello he creado mediante el designer un panel, que a su vez contiene un label "Título" y otro label "Texto". Posteriormente voy publicando en el ScrollView una copia de este panel por cada una de las noticias.

Añadido a esto quiero que el usario pueda aumentar o reducir el tamaño de fuente con sendos botones. Esto lo hago de manera que, tras pulsar el botón correspondiente, voy recorriendo mediante un bucle todos los views contenidos dentro del panel del SV y a aquellos que son un Label, les indico que ha de aumentarse el tamaño de la fuente.

Adjunto un ejemplo, donde he sustituido la carga de datos desde una BD, por un método provisional.

Este ejemplo me funciona correctamente, pero lo que quiero consultar a los que tenéis más experiencias que yo es si el método usado (tanto para publicar las noticias en el SV, como la modificación posterior del tamaño de fuente a demanda del usuario) es adecuado. Me pregunto si sería mejor usar una Clase. Me cuesta trabajo descubrir en qué casos he de usar una Clase para conseguir determinado objetivo.

Gracias.

(Reconozco que el título quizás sea poco descriptivo para lo que consulto)

B4X:
Sub Activity_Create(FirstTime As Boolean)
    scvInformaciones.Initialize(0)
    lstInformaciones.Initialize

    btSubeFuente.Initialize("btsubefuente")
    btSubeFuente.Text = "Sube"

'    lstInformaciones = DBUtils.ExecuteMemoryTable(Starter.sql, "SELECT titulo, texto FROM informaciones WHERE id_inf= ?", Array As String ("ab12"), 0)
'    Por simplificar este ejemplo, la carga de los datos desde una base de datos (linea anterior)
'    la he sustituido por las 4 líneas siguientes

    strContenido = Array As String("Título", "Texto ejemplo. Texto ejemplo. Texto ejemplo. Texto ejemplo. Texto ejemplo. Texto ejemplo. ")
    For n = 1 To 10
        lstInformaciones.Add(strContenido)
    Next

    Activity.AddView(scvInformaciones, 0, 0, 100%x, 90%y) 'Scroll para alojar las informaciones (noticias)
    Activity.AddView(btSubeFuente, 0, 90%y, 100%x, 10%y) 'Botón para subir fuente

    Dim UnaInformacion() As String

'    Publicación en el ScrollView de 10 copias del Layout "muestra_informaciones"
    For Numero = 0 To lstInformaciones.Size - 1
    
'        "muestra_informaciones" es un panel que contiene 2 Label
        scvInformaciones.Panel.LoadLayout("muestra_informaciones")

        pnlInformacion.Top = Numero * (pnlInformacion.Height + 4dip)

'        Extrae del List el contenido de una Información a publicar    
        UnaInformacion = lstInformaciones.get(Numero)
    
        lblTitulo.Text = UnaInformacion(0)
        lblInformacion.Text = UnaInformacion(1)
    Next
    scvInformaciones.Panel.Height = lstInformaciones.Size * (pnlInformacion.Height + 4dip)
End Sub

Sub btSubeFuente_click
    For Each vw As View In scvInformaciones.Panel.GetAllViewsRecursive
    If vw Is Label Then
            subefuente (vw)
        End If
    Next
End Sub

Sub subefuente (vw As Label)
    vw.TextSize = vw.Textsize + 1
End Sub
 

Attachments

  • cambio_fuente.zip
    8.5 KB · Views: 158
Last edited:

Carlos marin

Active Member
Licensed User
Hola séneca, se ve genial amigo, que tal si también le añadimos un imageview para cargar noticias con imagenes, mmm depronto también una fecha para mostras articulos que no lleven mas de x dias. lo digo por que por ejemplo tengamos una BD de mas de mil noticias no se cuelgue... ese codigo si me interesa
 

Seneca

Active Member
Licensed User
Hola.

En realidad el ejemplo de arriba es una versión simplificada de lo que he desarrollado. Con este ejemplo lo que quería consultar es si he escogido un buen método para publicar las noticias, y el posterior cambio del tamaño de letra a demanda del cliente.

En el código completo, además de lo que aparece en el ejemplo, he implementado una fecha de expiración para cada noticia de manera que solo se muestren las no expiradas. Bastaría crear el filtro correspondiente a la hora de hacer la consulta en la BD. También he configurado para que el alto del Label que muestra la noticia se ajuste, dependiendo de la longitud del texto de cada una de ellas y del tamaño de fuente escogido. Tengo pendiente incluir una imagen en cada noticia.

Gracias por las sugerencias.
 

dar2o3

Active Member
Licensed User
Buenos días.

Respecto al tema de cuando utilizar una clase (todo son instancias a clases aquí) entiendo que te refieres a cuando interesa crear una clase propia, en tu caso supongamos que llega un momento en que tienes mas de 500 noticias para mostrar, sería interesante que en vez de cargar todas de golpe, ir cargando en memoria las que vas a mostrar y otras tantas por detras y por delante, para así poder mostrarlas al usuario de forma rápida cuando haga scroll, dependiendo del la noticia en la que el usuario pare el scroll hacer la precarga de otras tantas noticias, crear una clase nueva que haga todo esto es sencillo y reutilizable, aquí es donde te interesa crearte tu propia clase.
 
Last edited:

Seneca

Active Member
Licensed User
Hola.

Sí, me refería a crear una clase propia. En mi caso el número de noticias a publicar es pequeño y, por lo que me indicas @dar2o3, no sería necesario el implementar una clase. Aún así me viene muy bien conocer el caso que has expuesto. Investigaré en ello.

Gracias.
 

Jhonn

Member
Hola, no se si sera correcto pero probe tu código para saber si te podía ayudar y funciona, pero por ejemplo cuando utilizas en android el esquema del xml, pone que <scrollview> con su etiqueta encierra el resto de views o controles dentro... yo lo tengo hecho de otra forma diferente a la tuya, yo cargo el layout para el panel una sola vez, y luego agrego cada control o view directamente a través de ScrollView1.Panel.AddView() tomando como referencia el único view o control que puse en el diseño para crear el resto copiando sus propiedades de colores y demás, es decir los agrego dinamicamente mediante código, pero la forma que tu utilizaste es mucho mas sencilla., pero no tengo ni idea si es correcta o no.

Ademas hice una prueba usar tu código y modificar los datos, y funcionaba, pensaba que iba dar error al modificar los datos, pero directamente asocio de manera correcta los datos.

Una de las cosas que yo he preguntado por si alguno no la sabe, es cuando agregas el scrollview, este tiene un panel interno el cual no genera ningún evento que no se porque será así, ya lo averiguaré...

Cuando creas una clase, creas tus objetos, las funciones que va a manejar este objeto, sus métodos y sus eventos, como se crea y se destruye, imaginemos, que creas tu clase para ejemplo que se llame Noticias, pues cuando vayas a utilizar tu clase harás algo así como

Dim noticias as Noticias : Noticias.Initialize
Noticias.CargarNoticias("archivodenoticias.txt") 'Supongamos que esto carga las noticias desde un archivo
Noticia.MostrarNoticias() 'Esto las muestra por pantalla
Dim resultados as List = Noticias.BuscarNoticia("programación") 'Esto busca las noticias relacionadas con la palabra "programación"

Es decir al crear tu clase con tus códigos, estas haciendo que tu cogido se mas fácil de manejar cuando estas programando, porque por decirlo de alguna forma ya lo tienes hecho, y lo puedes utilizar en cualquier otro programa u otra clase.

Es como cuando estas programando cualquier cosas por ejemplo creas un botón, y tu para crear el botón escribes: Dim button as Button, ya alguien creo la clase botón, y tu las estas utilizando, sin saber su código, sino existiera la clase botón, y tu necesitaras un botón tendrías crearla desde cero.
 

Seneca

Active Member
Licensed User
Hola.

La ventaja que yo le veo a cargar varias veces el Layout, que a su vez contiene un panel y este contiene el título y el texto de la noticia, es que puedo separar ligeramente (en sentido vertical) cada uno de los paneles, que al tener un color de fondo distinto al Activity, me delimita visualmente cada una de las noticias.

Separa verticalmente 4di cada panel que inserto en el ScrollView:
B4X:
 pnlInformacion.Top = Numero * (pnlInformacion.Height + 4dip)


El ejemplo que puse en el mensjae #1 incluye lo siguiente:
B4X:
Sub btSubeFuente_click
    For Each vw As View In scvInformaciones.Panel.GetAllViewsRecursive
    If vw Is Label Then
            subefuente (vw)
        End If
    Next
End Sub

Con esto se recorría de manera correlativa y recursiva todos los Views insertados en el ScrolView, independientemente de que fuesen Panel o Label.

Con la siguiente variante, lo hago de manera más ordenada, recorriendo primero cada unos de los paneles y dentro de cada uno de ellos recorro los Labels. Al hacer esto último compruebo el Tag de cada Label (que previamente he configurado en el Designer) para así hacer cosas diferentes con los Label "titulo" y los Labels "texto".

B4X:
Sub btSubeFuente_click
For Each vw As Panel In scvPromociones.Panel 'Recorre los paneles publicado en el ScrollView
        For Each vw1 As Label In vw 'Recorre cada Label que forma parte de casa unos de los paneles anteriores
            Select Case vw1.tag 'Comprueba el contenido del Tag de cada Label
                Case "titulo"
                    'Hace lo que queramos
                    .............
                    .............
                Case "texto"
                     subefuente (vw)
            End Select
        Next
Next
End Sub

De esta manera también me es fácil reconfigurar el Height de cada panel según necesite al aumentar el tamaño de fuente de los Labels internos.

......

Desconocía lo que comentas del XML. La verdad es que no me había dado por curiosear que encontraba por ahí. Indagaré.

Efectivamente, como he leido que te comentó Erel en otro hilo, el ScrollView trae implícito un Panel que no produce ningún evento, solo sirve como contenedor de otros Views "hijos" que son los que han de generar eventos (https://www.b4x.com/android/help/views.html#scrollview)

Gracias por la información sobre el uso de las Clases propias. En hilos anteriores otros compañeros, como @bgsoft , me han ido aclarando su funcionamiento, pero me cuesta trabajillo retener en mente esto de las clases. Supongo que es cuestión de tiempo y práctica.

Saludos.
 
Top