Spanish [SOLUCIONADO] (B4A) Botón con imagen de fondo, esquinas redondas y banda semitransparente

Seneca

Active Member
Licensed User
Hola a toda la comunidad.

Como no he encontrado un hilo para presentaciones y saludos, aprovecho mi primera consulta para empezar agradeciendo a todos los que dedican su tiempo no solo para que este foro en castellano exista, sino para que lo haga de manera ordenada.

Estoy buscando la mejor manera de crear mediante código un botón con imagen de fondo, y una banda de color semitransparente debajo del texto del propio botón, tal y como aparece en la imagen adjunta. Comentar que tanto el radio de redondeo de las esquinas, como el alto, color y opacidad de la banda han de generarse mediante código, de manera que me permirta personalizar el aspecto final del botón.

Explico el procedimiento que he pensado, solicitando opiniones de si es una forma correcta de hacerlo.
  1. Dimensiono un Bitmap y lo inicializo con Initializemutable (para que me permita modificarlo con Canvas), dándole las dimensiones del botón.
  2. Mediante Canvas incorporo la imagen del icono al Bitmap anterior
  3. Mediante Canvas dibujo el rectángulo de color semitransparente en el Bitmap anterior
  4. Redondeo el Bitmap anterior usando RoundCorner (Librería RSImageProcessing)
  5. Mediante Canvas asigno el Bitmap anterior, ya redondeado, al botón

Gracias por la ayuda.
 

Attachments

  • boton_redondeado.png
    boton_redondeado.png
    37.4 KB · Views: 582

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Seneca, bienvenido al foro:

Como decia Diógenes: El movimiento se demuestra... huyendo :D (es andando, pero me gusta mas lo otro)

Te pongo un ejemplo rápido en el cual puedes controlar TODOS los parámetros y es algo muy facil, puedes controlar el nivel de transparencia de la etiqueta, el color de fondo, la posición, el radio de las esquinas, el tipo de carga de la imagen, e incluso si haces el panel mas alto puedes poner la etiqueta debajo de la imagen.
Te adjunto dos imagenes, en una la etiqueta es completamente redonda, y en la otra como en tu ejemplo

B4X:
    Dim Clrs(2) As Int
    Clrs(0) = Colors.White
    Clrs(1) = Colors.White
    Dim Gradient1 As GradientDrawable
    Gradient1.Initialize("TL_BR",Clrs) ' de esquina izquierda arriba a esquina derecha abajo
    Gradient1.CornerRadius = 15dip ' con esto consigues los bordes redondeados, pon el tamaño que quieras

    Dim PanelBoton As Panel
    PanelBoton.Initialize("boton")
    PanelBoton.Background = Gradient1
    Activity.AddView(PanelBoton,50%x-75dip,50%y-75dip,150dip,150dip)

    Dim boton As ImageView
    boton.Initialize("boton")
    boton.Gravity=Gravity.FILL
    boton.Bitmap = LoadBitmapSample(File.DirAssets, "pelotabasket.png",15%x,15%y) ' controlas la carga en memoria si son muchos
    'boton.Bitmap = LoadBitmap((File.DirAssets, "pelotabasket.png") la otra opcion de carga
    PanelBoton.AddView(boton,10dip,10dip,130dip,130dip)

    Dim Texto As Label
    Texto.Initialize("boton")
    Texto.Text = "BALONCESTO"
    Texto.TextColor = Colors.White
    Texto.TextSize = 20
    Texto.Gravity=Bit.Or(Gravity.CENTER_HORIZONTAL, Gravity.TOP)
    Texto.Background = Gradient1 ' si lo comentas no sale con radio, como mas te guste
    Texto.Color = Colors.ARGB(170,0,0,0)' controlas lo transparente con el primer parámetro
    PanelBoton.AddView(Texto,0,120dip,150dip,50dip)

Si tienes que cargar muchas imagenes, para que no te desborde la memoria, te he puesto esto:
B4X:
boton.Bitmap = LoadBitmapSample(File.DirAssets, "pelotabasket.png",15%x,15%y)
cambiando los ultimos valores puedes dar mas calidad o menos, con ese valor he echo las capturas

Si cambias esta linea, puedes jugar con el color del gradiente, aqui te saldria de blanco a azul (ver captura adjunta)
B4X:
Clrs(1) =Colors.ARGB(100,0,0,255)

Con esta linea puedes cambiar el sentido del gradiente
B4X:
Gradient1.Initialize("TL_BR",Clrs) ' de esquina izquierda arriba a esquina derecha abajo

He puesto muchas caracteristicas de tamaño, etc, que si quieres las puedes quitar y el codigo seria mas corto

Saludos
 

Attachments

  • Como el tuyo.jpg
    Como el tuyo.jpg
    53.1 KB · Views: 533
  • etiqueta redonda.jpg
    etiqueta redonda.jpg
    54.7 KB · Views: 592
  • gradiente azul.jpg
    gradiente azul.jpg
    54.6 KB · Views: 541
Last edited:

Seneca

Active Member
Licensed User
Gracias Jesús por la rápida y detallada respuesta.

He estado probando el código que me aportas y me presenta el inconveniente de que solo es válido cuando se usan imágenes con fondo transparente o de color liso. Si quiero usar una imagen que ocupe todo la superficie del botón, las esquinas no quedan redondeadas. También he comprobado que en el archivo "Como el tuyo.jpg" que adjuntas, las esquinas inferiores aunque aparecen redondeadas, adicionalmente muetran en color oscuro las esquinas cuadradas.

He probado a desarrollar la idea que planteaba en mi primer mensaje usando la librería RSImageEffects y he podido obtener el resultado que buscaba, incluso usando imágenes de fondo "completas" (sin fondo transparente). Lo que ya dudo es que este código mío esté optimizado.

Explico el procedimiento que he pensado, solicitando opiniones de si es una forma correcta de hacerlo.
  1. Dimensiono un Bitmap y lo inicializo con Initializemutable (para que me permita modificarlo con Canvas), dándole las dimensiones del botón.
  2. Mediante Canvas incorporo la imagen del icono al Bitmap anterior
  3. Mediante Canvas dibujo el rectángulo de color semitransparente en el Bitmap anterior
  4. Redondeo el Bitmap anterior usando RoundCorner (Librería RSImageProcessing)
  5. Mediante Canvas asigno el Bitmap anterior, ya redondeado, al botón

Lo que sí me he dado cuenta es que en el punto 5 no es necesario Canvas para asignar la imagen al botón, sino que bastaba con .SetBackgroundImage

B4X:
Dim IE As RSImageEffects
    Dim btn As Button
    btn.Initialize("boton")
  
    Dim DestRect As Rect
    Dim icono As Bitmap
    Dim iconoCanvas As Canvas ' mediante canvas inserto la imagen y la franja de color, para despues redondear todo
  
    Activity.AddView(btn, 50%x-75dip,50%y-75dip,150dip,150dip)
  
    icono.InitializeMutable(btn.Width,btn.Width) ' inicializo el icono como bitmat modificable por el canvas con el tamaño del botón

    DestRect.Initialize(0dip, 0dip, btn.Width, btn.Height)
  
    iconoCanvas.Initialize2(icono)

    'Cargo la imagen en el bitmap "Icono" mediante Canvas
    iconoCanvas.DrawBitmap(LoadBitmapSample(File.DirAssets, "pelotabasket.jpg",15%x,15%y), Null, DestRect)

    'Recuadro Gris con alpha sobre icono
    Dim RectColor As Rect
    RectColor.Initialize(0dip, btn.Height-30dip, btn.Width,btn.Height)
    iconoCanvas.DrawRect(RectColor, Colors.ARGB(160,0,0,0), True, 1dip)

     btn.SetBackgroundImage(IE.RoundCorner(icono,28)) 'redondea el icono con la franja y lo coloca en el botón

    btn.Gravity=Bit.Or(Gravity.BOTTOM, Gravity.CENTER_HORIZONTAL)
    btn.Text = "BALONCESTO"
    btn.TextSize = 18
    btn.TextColor=Colors.White

Aprecio que el texto del botón se me queda desplazado hacia arriba, pero tengo que buscar un post en el que se indicaba cómo ajustar el Padding de los botones.

Adjunto imagen del resultado que he obtenido.

Saludos.
 

Attachments

  • boton_redondeado.jpg
    boton_redondeado.jpg
    41.9 KB · Views: 524
Last edited:

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Séneca:

No todo es perfecto cuando haces un código en un momento a modo de ejemplo, es a quien se le hace el código quien tiene que añadir las cosas que le interesen, si no, los que ayudamos nos convertiriamos en "los que les hacen el código a los demas" , y creo que esa no es la labor de un foro. Por otra parte siempre es interesante que a quien se le haga el codigo haga pruebas de como solucionar depende que problemas, y cuando ya no llega volver a preguntar.

Si quiero usar una imagen que ocupe todo la superficie del botón, las esquinas no quedan redondeadas
Si, por que el ImagenView no acepta el gradiente con las esquinas redondeadas, la solución es hacer las esquinas mas pequeñas, y poner la imagen en el top y el left pasada las esquinas, quedará algo mas pequeña, pero tampoco excesivamente.

También he comprobado que en el archivo "Como el tuyo.jpg" que adjuntas, las esquinas inferiores aunque aparecen redondeadas, adicionalmente muetran en color oscuro las esquinas cuadradas.
Si, por que al no haberle pasado el gradiente es un rectangulo, y como el left estaba a cero queda solapado lo de abajo, la solucion es la misma de arriba, hacerlo mas pequeño que la esquina o bien poner el gradiente.

He estado probando el código que me aportas y me presenta el inconveniente de que solo es válido cuando se usan imágenes con fondo transparente o de color liso
Esto no entiendo a que te refieres, ya que la imagen al estar incrustada en el panel puedes ponerla donde quieras.

Aprecio que el texto del botón se me queda desplazado hacia arriba, pero tengo que buscar un post en el que se indicaba cómo ajustar el Padding de los botones.

Lláma a este sub y podras mover el texto.
B4X:
Sub SetPadding(v As View, Left As Int, Top As Int, Right As Int, Bottom As Int)
 Dim jo As JavaObject = v ' Biblioteca JavaObject
 jo.RunMethod("setPadding", Array As Object(Left, Top, Right, Bottom))
End Sub

Saludos
 

Seneca

Active Member
Licensed User
Gracias Jesús por las nuevas aportaciones y por los detalles de cómo solucionar los inconvenientes que encontré. Espero que mis comentarios no sonasen a reproche. Estoy más que agradecido a que dedicases tiempo no sólo a explicarme, sino a desarrollar el código que, como bien dices, es la base sobre la que he de trabajar.

El sub para ajustar el padding, perfecto.

Saludos.
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Séneca:

Espero que mis comentarios no sonasen a reproche
Si tus comentarios me hubiesen sonado a reproche no te hubiese contestado :D , solo quise decir que siempre es interesante desarrollar sobre la idea que te dan, por que eso te hace aprender, si te lo dan todo echo no aprendes nada.

Ya te iras dando cuenta que Android no tiene nada que ver con otros SO que hayas desarrollado, y veras que soluciones simples en otros lenguajes y SO aqui se te puede complicar, tambien en B4A hay cosas que superan en facilidad y potencia a otros sistemas de desarrollo a la hora de hacer algun código concreto.

Me alegro que ese sub te haya solucionado el problema.

Saludos
 
Top