Spanish Crear chat o foro Tipo Whatsapp [SOLUCIONADO]

Carlos marin

Active Member
Licensed User
Longtime User
Hola compañeros. bueno estoy tratando de crear una especie de foro. estoy usando el customlistview para mostrar lo que se va agregando pero tengo los siguientes problemas.

1 estoy usando un AutoTextSizeLabel de este hilo que me proporciono jordi https://www.b4x.com/android/forum/threads/custom-view-autotextsizelabel.30642/#content, pero realmente lo que necesito es que la caja de texto se ajuste a la cadena que yo le mande así como el whatsapp. ya que cuando mando cadenas de texto muy extensas me muestra la letra muy pequeña.

2 bueno tengo una caja de texto pero también quiero que haga lo mismo que el whatsapp cuando le das clic para escribir, esta caja de texto se desplaza hacia arriba (mitad mas o menos) y abre el teclado en la parte de abajo. también el panel donde muestra lo que uno a enviado queda desplazado hacia arriba. lo e intentado y no e podido hacerlo. bueno agradeceria mucho su ayuda. gracias

asi es como me esta quedando es muy crudo. la logica es asi. manda al servidor y el servidor a la app





 

Attachments

  • p1.png
    p1.png
    31.9 KB · Views: 533
  • p2.png
    p2.png
    50.4 KB · Views: 734
  • p3.png
    p3.png
    33.2 KB · Views: 514
Last edited:

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Carlos:

Como decia Jack el destripador; vayamos por partes :D

pero realmente lo que necesito es que la caja de texto se ajuste a la cadena que yo le mande así como el whatsapp. ya que cuando mando cadenas de texto muy extensas me muestra la letra muy pequeña.

Parto de la base que los textos lo estas incrustando en un scrollwiew para poder poner uno tras otro y poder moverte de arriba abajo.
En vez de emplear un AutoTextSizeLabel , emplea un label normal, de esta forma tu controlas el tamaño del texto (TextSize), la alineación, etc. Dale el ancho que quieras (100%x por ejemplo) y cambiale el alto utilizando esta rutina:

B4X:
sub Globals
TopBocadillo= 0 as int ' para poner uno tras otro
...



     dim TextoBocadillo ="Prueba de texto, hazlo largo para ver como se comporta" as string
     Dim Txt_Bocadillo As Label  ' lo de bocadillo es por el globo de los tebeos cuando alguien habla :D
     Txt_Bocadillo.Initialize("Nombre del evento que quieras por si lo vas a emplear")
     Txt_Bocadillo.TextSize = 22  ' el valor que quieras
     Txt_Bocadillo.TextColor = Colors.white ' el valor que quieras
      Txt_Bocadillo.Color = Colors.blue ' el valor que quieras
     Txt_Bocadillo.Gravity = Bit.Or(Gravity.CENTER_HORIZONTAL,Gravity.CENTER_VERTICAL) ' centrado total
     Txt_Bocadillo.Text = TextoBocadillo
     Scroll1.Panel.AddView(Txt_Bocadillo,0,TopBocadillo,100%x,-6)
  
  
   Dim ht As Float
   Dim StrUtil As StringUtils     ' libreria StringUtils              
   ht =    StrUtil.MeasureMultilineTextHeight(Txt_Bocadillo, TextoBocadillo)
   Txt_Bocadillo.Height = ht  ' si quieres darle unos dip mas para que quede espacio arriba y abajo sumalo
   Scroll1.Panel.Height = ht
   TopBocadillo = TopBocadillo + ht + 5dip ' dale el espacio que quieras

Con esto ya tienes el control del texto

Y de regalo :D, si quieres poner la forma de "bocadillo" tipo Whatsapp puedes hacerlo asi:
B4X:
   ' añade esto antes del initialize
   Dim r As Reflector ' Libreria Reflection
   Dim package As String
   Dim id As Int
   ' -----------------------------------
   Txt_Bocadillo.Initialize("Nombre del evento que quieras por si lo vas a emplear") ' despues de esto pon lo siguiente
   ' -----------------------------------
   package = r.GetStaticField("anywheresoftware.b4a.BA", "packageName")
   id = r.GetStaticField(package & ".R$drawable", "bocadilloarriba")
   r.Target = r.GetContext
   r.Target = r.RunMethod("getResources")
   Txt_Bocadillo.Background = r.RunMethod2("getDrawable", id, "java.lang.int")

En la carpeta \Objects\res\drawable añade este icono bocadilloarriba.9.png que te lo adjunto, es con la flecha arriba, pon la flecha donde tu quieras, acuerdate de hacerlo de solo lectura cuando lo modifiques

2 bueno tengo una caja de texto pero también quiero que haga lo mismo que el whatsapp cuando le das clic para escribir, esta caja de texto se desplaza hacia arriba (mitad mas o menos) y abre el teclado en la parte de abajo. también el panel donde muestra lo que uno a enviado queda desplazado hacia arriba. lo e intentado y no e podido hacerlo. bueno agradeceria mucho su ayuda. gracias
Si te fijas en el WhatsApp donde escribes está abajo fijo (no en el scroll) y sube cuando te pones a escribir, tienes dos soluciones, o lo subes tu hasta una distancia que creas correcta cuando coja el foco, o lo haces con esta rutina que ya he dado otras veces. Se sobreentiende que el editext está incrustado en un panel (lo he llamado PanelInMensaje)
B4X:
Sub Globals
Dim IME As IME
Dim TopInMensaje as int

Sub Activity_Create(FirstTime As Boolean)
IME.Initialize("IME")
IME.AddHeightChangedEvent
TopInMensaje = PanelInMensaje.Top
IME_HeightChanged(-60%y,0) ' llamar manualmente a este método para establecer la disposición de teclado
PanelInMensaje.Top = TopInMensaje
...



Sub IME_HeightChanged(NewHeight As Int, OldHeight As Int)' para subir la entrada de datos y que este encima del teclado
  ' el 600 es el valor que te vaya mejor haciendo pruebas antes
  If NewHeight-In_Mensaje.Height> 600 Then ' In_Mensaje es el editext donde se escribe el mensaje a enviar
     PanelInMensaje.Top = TopInMensaje
   Else
     PanelInMensaje.Top= NewHeight-In_Mensaje.Height
   End If 

End Sub

Saludos
 

Attachments

  • bocadilloarriba.9.png
    bocadilloarriba.9.png
    397 bytes · Views: 360

Carlos marin

Active Member
Licensed User
Longtime User
hola bgsoft amigo mil gracias por la ayuda, una pregunta mas, es posible hacerlo con un customlistview ya que lo puedo diseñar a mi gusto, lo que no se es si con el customlistview se pueda re dimensionar el panel, lo tengo asi
cuando consulto la base de datos llamo al CreateListItem y le doy un alto predeterminado (155dip).

B4X:
clv.Add(CreateListItem($"Item #${i}"$, clv.AsView.Width, TopBocadillo), 155dip, id)

y en el evento CreateListItem

B4X:
Sub CreateListItem(Text As String, Width As Int, Height As Int) As Panel
    Dim p As Panel
    p.Initialize("")
    Activity.AddView(P, 0, 0, Width, Height)
    P.LoadLayout("CellItem2")
    P.RemoveView
    lblmensaje.Text = descripcion
    lblasunto.Text = asunto
    lblfecha.Text = fecha
    lblusuario.Text = usuario
    lblresp.Text = resp
    Return P
End Sub

pero intento re dimensionar el panel para que se ajuste al label al que le envio la cadena y no me deja.
 
Last edited:

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Carlos:

Un customlistview no es otra cosa que un módulo de clase que emplea un scrollview para mejorar lo que seria un ListView, por lo tanto si sabes añadir objetos al scrollview verás que no tiene ningún misterio.

En tu código hay varios errores: En el add le pasas como altura del panel un valor fijo (155dip) pasas a CreateListItem el top del bocadillo, tienes que pasarle el alto, no a que altura. En el CreateListItem Incrustas el panel en el activity (eso ya lo hace cuando llamas al Add) cargas un layout y despúes lo quitas con removeView. En definitiva, si has creado un item por medio de CustomlistView, a menos que modifiques el codigo del modulo de clase, tu ya no tienes el control de los tamaños una vez añadido.

Puedes hacer varias cosas, si necesitas diferentes layout incluido el del "bocadillo" create llamadas al Add con diferentes CreateListItem.
En el que te interesa tener la altura del texto, hazlo como te escribí mas arriba, y el alto resultante se lo pones al label y al panel. Luego en el Add le pasas la altura de ese mismo panel. Si se te complica mucho, create una variable global con la altura resultante del bocadillo y se la pasas al Add

Mirate el código del modulo de clase en el Add, y veras como lo incrusta donde tu le hayas dicho. Si repasas un poco el Initialize y los diferentes Add, veras que simplemente incrusta donde tu le digas y con los tamaños pasados.
Si aun tienes dudas de como funciona un scrollview, mirate el tutorial de Erel:
https://www.b4x.com/android/forum/threads/scrollview-example.6612/#content


Saludos
 

Carlos marin

Active Member
Licensed User
Longtime User
Buenos días, muchas gracias por sus aportes, aquí dejo el código por si alguien mas adelante lo necesite y ps si se puede mejorar sea todo bienvenido. mil gracias

B4X:
Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
        hc.Initialize("hc")
    End If
    Activity.LoadLayout("foro")
    server.Initialize(0, "")
    IME.Initialize("IME")
    IME.AddHeightChangedEvent
    IME_HeightChanged(100%y, 0) 'manually call this method to set the layout of EditText1 and btnHideKeyboard

    Dim pantalla As Float ' dependiendo del tamaño de pantalla cargo el tamaño de letra
    pantalla = GetDeviceLayoutValues.ApproximateScreenSize
    If pantalla <= 4 Then Tam_letra = 1
    If pantalla > 4 And pantalla < 4.5 Then Tam_letra = 2
    If pantalla >= 4.5 Then Tam_letra = 3
    cargar_list
End Sub

Sub IME_HeightChanged(NewHeight As Int, OldHeight As Int)  ' cuando el teclado se muestra entra a este evento
    PnlHideKeyboard.Top = NewHeight - PnlHideKeyboard.Height 'PnlHideKeyboard es el panel donde esta la caja de texto y botón enviar conversación
    ScrollView2.Height = PnlHideKeyboard.Top - ScrollView2.Top
End Sub


Sub hc_ResponseSuccess (Response As HttpResponse, tarea As Int)
    Dim res As String
    res = Response.GetString("UTF8")
    Log("Resp: " & res)
    Dim parser As JSONParser
    parser.Initialize(res)
    Dim l As List
        l.Initialize
        l = parser.NextArray
      
    Select tarea

    Case 1
        If l.Size = 0 Then
            Log("no se encuentran datos!")
            ToastMessageShow("No hay temas en discucion en el momento",False)
             p1.Visible = False
             btnnuevof.Visible = True
             Pvista.Visible = True
             'pnuevotema.Visible = False
             'Presp.Visible = False  
             TopBocadillo = 0
             ProgressDialogHide
        Else
          
            For i = 0 To l.Size - 1
                Dim m As Map
                m = l.Get(i)
                'TRAIGO EL FORO CONSULTADO
                    id= m.Get("id")
                    cod= m.Get("cod")
                    asunto= m.Get("asunto")
                    usuario= m.Get("usuario")
                    descripcion= m.Get("descripcion")
                    fecha= m.Get("fecha")
            
                    v(id,0) = cod
                    v(id,1) = usuario
                    v(id,2) = descripcion
                    v(id,3) = fecha  
                    v(id,4) = asunto  
                      
                    Dim total, total1 As String
                    Dim Txt_Bocadillo, Txt_titulo, txt_fecha As Label  ' lo de bocadillo es por el globo de los tebeos cuando alguien habla :D
                    Txt_Bocadillo.Initialize("lblmensaje")
                    Txt_titulo.Initialize("")
                    txt_fecha.Initialize("")
                    'Txt_Bocadillo.TextSize = 12    ' el valor que quieras
                  
                    Txt_Bocadillo.TextColor = Colors.Black
                    Txt_Bocadillo.Color = Colors.White
                    Txt_Bocadillo.Gravity = Bit.Or(Gravity.LEFT,Gravity.TOP)
                    Txt_Bocadillo.Typeface = Typeface.DEFAULT
                  
                    Txt_titulo.TextColor = Colors.DarkGray
                    Txt_titulo.Color = Colors.White
                    Txt_titulo.Gravity = Bit.Or(Gravity.CENTER_VERTICAL,Gravity.BOTTOM)
                    Txt_titulo.Typeface = Typeface.DEFAULT
                  
                    txt_fecha.TextColor = Colors.DarkGray
                    txt_fecha.Color = Colors.White
                    txt_fecha.Gravity = Bit.Or(Gravity.TOP,Gravity.RIGHT)
                    txt_fecha.Typeface = Typeface.DEFAULT
                    txt_fecha.TextSize = 12
                    Txt_titulo.TextSize = 12
                    total1 = usuario
                    total = asunto & CRLF
                    txt_fecha.Text = fecha
                    Txt_titulo.Text = total1
                    Txt_Bocadillo.Text = total
                    Txt_Bocadillo.Tag = id
                    Select Tam_letra
                        Case 1
                            Txt_Bocadillo.TextSize = 10
                            'PANTALLAS TAMAÑO MEDIANO MAYOR 4.0 dip
                            ScrollView1.Panel.AddView(Txt_titulo,1,TopBocadillo,100%x,10)
                            ScrollView1.Panel.AddView(txt_fecha,200,TopBocadillo,70%x,50)
                            TopBocadillo = TopBocadillo + 50              
                            ScrollView1.Panel.AddView(Txt_Bocadillo,1,TopBocadillo,100%x,10)
                            Dim ht,ht1 As Float
                            Dim StrUtil As StringUtils            
                            ht = StrUtil.MeasureMultilineTextHeight(Txt_Bocadillo,total)
                            ht1 = StrUtil.MeasureMultilineTextHeight(Txt_titulo,total1)
                            Txt_Bocadillo.Height = ht + 5dip '
                            Txt_titulo.Height = ht1
                            TopBocadillo = TopBocadillo + ht + 6dip
                            ScrollView1.Panel.Height =     TopBocadillo
                        Case 2
                            Txt_Bocadillo.TextSize = 13  
                            'PANTALLAS TAMAÑO MEDIANO MAYOR 4.0 dip
                            ScrollView1.Panel.AddView(Txt_titulo,1,TopBocadillo,100%x,10)
                            ScrollView1.Panel.AddView(txt_fecha,200,TopBocadillo,70%x,50)
                            TopBocadillo = TopBocadillo + 50              
                            ScrollView1.Panel.AddView(Txt_Bocadillo,1,TopBocadillo,100%x,10)
                            Dim ht,ht1 As Float
                            Dim StrUtil As StringUtils          
                            ht = StrUtil.MeasureMultilineTextHeight(Txt_Bocadillo,total)
                            ht1 = StrUtil.MeasureMultilineTextHeight(Txt_titulo,total1)
                            Txt_Bocadillo.Height = ht + 5dip
                            Txt_titulo.Height = ht1
                            TopBocadillo = TopBocadillo + ht + 6dip
                            ScrollView1.Panel.Height =     TopBocadillo
                              
                        Case 3
                            Txt_Bocadillo.TextSize = 16  
                            'ingreso el scrollview    16 dip
                            ScrollView1.Panel.AddView(Txt_titulo,1,TopBocadillo,100%x,10)
                            ScrollView1.Panel.AddView(txt_fecha,200,TopBocadillo,70%x,50)
                            TopBocadillo = TopBocadillo + 30              
                            ScrollView1.Panel.AddView(Txt_Bocadillo,1,TopBocadillo,100%x,10)
                            Dim ht,ht1 As Float
                            Dim StrUtil As StringUtils  
                            ht = StrUtil.MeasureMultilineTextHeight(Txt_Bocadillo,total)
                            ht1 = StrUtil.MeasureMultilineTextHeight(Txt_titulo,total1)
                            Txt_Bocadillo.Height = ht + 5dip
                            Txt_titulo.Height = ht1
                            TopBocadillo = TopBocadillo + ht + 6dip
                            ScrollView1.Panel.Height =     TopBocadillo
                                  
                    End Select
            Next
            ProgressDialogHide  
        End If

    End Select  
    Response.Release
End Sub
End Sub
 
Last edited:

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Carlos, solo es una critica constructiva, yo siempre pienso que si el codigo consigue lo que esperas está bien echo, pero puedes evitar muchas lineas de codigo si por ejemplo asignas el valor del tamaño del texto directamente:

En vez de esto:
B4X:
If pantalla <= 4Then Tam_letra = 1
If pantalla > 4 And pantalla < 4.5 Then Tam_letra = 2
If pantalla >= 4.5 Then Tam_letra = 3

Esto:
B4X:
If pantalla <= 4 Then Tam_letra = 10
If pantalla > 4 And pantalla < 4.5 Then Tam_letra = 13
If pantalla >= 4.5 Then Tam_letra = 16

Luego quitas el Select Tam_letra y pones el código de un solo case, ya que la unica diferencia entre casos es el tamaño del texto (creo):

B4X:
Txt_Bocadillo.TextSize = Tam_letra
ScrollView1.Panel.AddView(Txt_titulo,1,TopBocadillo,100%x,10)
ScrollView1.Panel.AddView(txt_fecha,200,TopBocadillo,70%x,50)
TopBocadillo = TopBocadillo + 50
ScrollView1.Panel.AddView(Txt_Bocadillo,1,TopBocadillo,100%x,10)Dim ht,ht1 As FloatDim StrUtil AsStringUtils
ht = StrUtil.MeasureMultilineTextHeight(Txt_Bocadillo,total)
ht1 = StrUtil.MeasureMultilineTextHeight(Txt_titulo,total1)
Txt_Bocadillo.Height = ht + 5dip' Txt_titulo.Height = ht1
TopBocadillo = TopBocadillo + ht + 6dip
ScrollView1.Panel.Height = TopBocadillo

De esa forma tambien se entiende facilmente el codigo pero escribes mucho menos.


Saludos y gracias por compartir
 
Last edited:

Carlos marin

Active Member
Licensed User
Longtime User
Hola Carlos, solo es una critica constructiva, yo siempre pienso que si el codigo consigue lo que esperas está bien echo, pero puedes evitar muchas lineas de codigo si por ejemplo asignas el valor del tamaño del texto directamente:

En vez de esto:
B4X:
If pantalla <= 4Then Tam_letra = 1
If pantalla > 4 And pantalla < 4.5 Then Tam_letra = 2
If pantalla >= 4.5 Then Tam_letra = 3

Esto:
B4X:
If pantalla <= 4 Then Tam_letra = 10
If pantalla > 4 And pantalla < 4.5 Then Tam_letra = 13
If pantalla >= 4.5 Then Tam_letra = 16

Luego quitas el Select Tam_letra y pones el código de un solo case, ya que la unica diferencia entre casos es el tamaño (creo):

B4X:
Txt_Bocadillo.TextSize = Tam_letra
ScrollView1.Panel.AddView(Txt_titulo,1,TopBocadillo,100%x,10)
ScrollView1.Panel.AddView(txt_fecha,200,TopBocadillo,70%x,50)
TopBocadillo = TopBocadillo + 50
ScrollView1.Panel.AddView(Txt_Bocadillo,1,TopBocadillo,100%x,10)Dim ht,ht1 As FloatDim StrUtil AsStringUtils
ht = StrUtil.MeasureMultilineTextHeight(Txt_Bocadillo,total)
ht1 = StrUtil.MeasureMultilineTextHeight(Txt_titulo,total1)
Txt_Bocadillo.Height = ht + 5dip' Txt_titulo.Height = ht1
TopBocadillo = TopBocadillo + ht + 6dip
ScrollView1.Panel.Height = TopBocadillo

De esa forma tambien se entiende facilmente el codigo pero escribes mucho menos.


Saludos y gracias por compartir

Amigo mil gracias si es mucho mejor. ;););):D:D:D:D
 
Top