Introducción A Los Modificadores De Redacción De Jetpack

Este artículo supone que el lector tiene conocimientos básicos sobre cómo funciona Jetpack Compose, si no está familiarizado con las @Composablefunciones anotadas, le aconsejo que estudie estos temas antes de leer este artículo.

Jetpack Compose es una biblioteca diseñada para traer patrones de IU declarativos al desarrollo de Android.

Es una función innovadora que cambia por completo la forma en que los desarrolladores tienen que pensar y diseñar su interfaz de usuario, dado que hay poco que ver con el (antiguo) sistema de vista XML.

Los Componibles predeterminados (basados ​​en la especificación Material UI) son altamente personalizables de forma predeterminada, pero la existencia de Modificadores aumenta las posibilidades de personalización a más de nueve mil.

Personalización de un componente regular

La mayoría de Composables son personalizables a través de sus parámetros, por ejemplo, podemos cambiar el color y el progreso actual de un CircularProgressBar(), o establecer íconos iniciales/posteriores para TextField()Composables.

Pero en la mayoría de los casos, esto puede no ser suficiente. Las cajas, por ejemplo, no tienen muchas opciones de personalización a través de sus parámetros.

@Composable
inline fun Box(
    modifier: Modifier = Modifier,
    contentAlignment: Alignment = Alignment.TopStart,
    propagateMinConstraints: Boolean = false,
    content: @Composable BoxScope.() -> Unit
)

Gist 1: Parámetros disponibles de Box Composable

Composable Box()no parece un componente muy flexible, dado que no tenemos parámetros explícitos para modificar los colores, la forma, los bordes, la altura, el ancho y muchas otras propiedades útiles para lograr el objetivo de la interfaz de usuario.

Pero la cuestión es que no necesitamos todos estos parámetros simplemente por la existencia de modificadores.

¿Qué es un modificador?

De acuerdo con la documentación de Android, un Modificador es un conjunto encadenado de propiedades que se pueden asignar a un Composable, capaz de modificar el diseño, agregar detectores de eventos y mucho más.

Imagen 1: Algunos de los modificadores disponibles para Box Composable dentro de un Scaffold.

Los modificadores se encadenan usando un patrón de fábrica, por lo que si deseamos establecer el color de fondo del cuadro en amarillo y establecer su altura y ancho, podríamos hacer algo como esto:


Box(
     modifier = Modifier
         .background(Color.Yellow)
         .height(60.dp)
         .width(100.dp)
 )

Gist 2: Colorear una caja y establecer sus dimensiones

Imagen 2: Resultado del código diseñado en Gist 2.

A veces es una cuestión de orden

Al realizar cambios menores en un Composable, el orden de los Modificadores puede no hacer ninguna diferencia, pero cuando se necesita un diseño más complejo, debemos prestar atención al orden de nuestros Modificadores encadenados. Para ejemplificar este uso, codificaremos el diseño a continuación:

Primero, vamos a crear la estructura base de nuestro diseño, con un Scaffold como el "esqueleto" de la pantalla y una caja para envolver nuestro contenido. Tenga en cuenta que ya estamos usando un modificador aquí Modifier.fillMaxSize()para hacer que Box Composable se ajuste al tamaño completo de Scaffold.

Scaffold {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        // Our content will be coded here 
    }
}

Ahora agreguemos nuestros componibles, modificadores y entendamos lo que está pasando aquí:

 Scaffold {
     Box(
         modifier = Modifier.fillMaxSize(),
         contentAlignment = Alignment.Center
     ) {
         Column(
             modifier = Modifier
                 .clip(CircleShape)
                 .fillMaxWidth(0.8f)
                 .aspectRatio(1f)
                 .background(Color.Gray),
             horizontalAlignment = Alignment.CenterHorizontally,
             verticalArrangement = Arrangement.Center
         ) {
             Text("I am text")
             Text("I am text too")
         }
     }
 }

Para lograr este diseño, decidí usar un cuadro como envoltorio de pantalla con el modificador fillMaxSize(), por lo que este mismo componible llenará todo el tamaño de su padre. Como complemento a la caja, utilicé una Columna para que fuera nuestro círculo con los elementos componibles de Texto dentro.

En este orden exacto Modifier, podemos lograr fácilmente el círculo gris con dos textos (uno encima del otro), ahora entendamos qué hace cada uno de los modificadores de la Columna y luego cambiemos su orden para causar que el diseño se rompa a propósito.

  • clip: El modificador de recorte sirve para recortar el Composable para que podamos cambiar fácilmente su forma. Usando este modificador podemos transformar un Box rectangular (la forma predeterminada del Box Composable) en un rectángulo de esquina redondeada o un círculo, por ejemplo.
  • fillMaxWidth: este modificador sirve para informar al componible para que se ajuste al ancho máximo del padre (esto es similar a una vista de ancho de 0dp restringida al inicio y al final de su padre cuando se usa Diseño de restricción). El parámetro de fracción sirve para definir el "peso" de este autorrelleno, por ejemplo, al usar 0.1f llenaremos el 10% del ancho del padre y 1.0f llenará todo el ancho disponible.
  • aspectRatio: Este modificador intentará igualar la altura y el ancho de un componible de acuerdo con el parámetro de proporción. Al usar clip , definimos nuestro componible como un círculo y fillMaxWidth establece que el diámetro de nuestro círculo llenará el 80% del ancho máximo del padre, pero esta solución no dará como resultado un círculo perfecto, al eliminar aspectRatio podemos ver que la columna tiene la forma de un rectángulo de esquinas redondeadas y no un círculo. Esto sucede porque el círculo necesita que la altura y el ancho retengan el mismo valor, por lo que al usar aspectRatio(1)podemos asegurarnos de que nuestro círculo tenga el mismo ancho y alto.

  • backgroundColor: Establece el color de fondo de un componible al valor dado. El backgroundColor es uno de los modificadores en los que importa el orden, y podemos ver este comportamiento si nos movemos backgroundColorantes del clipmodificador. Esto sucede porque esencialmente estamos pintando el componible antes de recortar sus límites, por cuestiones prácticas, nuestra Columna se recorta para ser un Círculo. Pero debido a que lo pintamos antes del recorte, parece que el clipmodificador no funciona, pero lo hace, es solo una cuestión de orden.
Column(
    modifier = Modifier
        .background(Color.Gray)
        .clip(CircleShape)
        .fillMaxWidth(0.8f)
        .aspectRatio(1f),
    horizontalAlignment = Alignment.CenterHorizontally,
    verticalArrangement = Arrangement.Center
) 

Modificadores contenidos en el alcance

La biblioteca Compose Standard ofrece toneladas de modificadores de alcance comunes, en otras palabras, modificadores que están disponibles de forma predeterminada, por lo tanto, independientes del alcance actual.

Pero cada vez que se usan Composables como Columna, Fila y Cuadro, probablemente haya notado que la contentlambda está envuelta dentro de un ámbito, por ejemplo, en las columnas que tenemos ColumnScope:

ColumnScopees una interfaz responsable de establecer la altura de Composable en relación con el tamaño de su contenido (envoltura de contenido de forma predeterminada), y también proporciona un conjunto limitado de modificadores que solo están disponibles dentro de este ámbito: weight, aligny alignBy, esto es lo que yo llamo ámbito- Modificadores retenidos.

Puede leer más sobre los ámbitos y sus respectivos modificadores retenidos accediendo al código fuente a través del IDE o leyendo la documentación oficial.

Si volvemos a nuestro diseño de columna en forma de círculo y agregamos el alignmodificador a nuestros TextComposables, podemos alinearlos horizontalmente en la columna

Estos modificadores de alineación también están disponibles en Row Composable, pero en este caso, son los encargados de alinear el contenido verticalmente dentro de la fila. Esto también es cierto para BoxScope, pero en este caso tenemos modificadores que pueden controlar la posición tanto horizontal como verticalmente.

 Column(
     modifier = Modifier
         .clip(CircleShape)
         .background(Color.Gray)
         .fillMaxWidth(0.8f)
         .aspectRatio(1f),
     horizontalAlignment = Alignment.CenterHorizontally,
     verticalArrangement = Arrangement.Center
 ) {
     Text("I am text", modifier = Modifier.align(Alignment.End))
     Text("I am text too", modifier = Modifier.align(Alignment.Start))
 }

Los cambios anteriores producirán el diseño a continuación, al agregar los alignmodificadores a nuestros Textcomponibles, tenemos control directo de su posición horizontal dentro de la Columna.

Modificadores de recombinación

Los modificadores también se pueden recombinar mediante la creación de un solo modificador que aplique otros modificadores, en nuestro caso, podemos crear uno makeColouredCircleque reciba un parámetro de color.


fun Modifier.makeColouredCircle(color: Color): Modifier =
    this.then(
        Modifier
            .clip(CircleShape)
            .background(color)
            .fillMaxWidth(0.8f)
            .aspectRatio(1f)
    )

Dado que los modificadores se encadenan uno tras otro, debemos garantizar que los agregados previamente no se perderán al aplicar nuestro modificador personalizado, es por eso que debemos usar la this.thendeclaración. La thenfunción sirve para agregar más modificadores a una instancia de modificador preexistente.

En este ejemplo, estamos agregando modificadores de medición en nuestro Modificador personalizado, pero tenga en cuenta que NO ES una buena práctica, por lo general, fillMaxWidth y aspectRatio debe usarse directamente en nuestro Column Composable

No tiene que preocuparse por tener en cuenta esta regla cada vez que cree un nuevo Modificador personalizado, si simplemente intenta devolver una nueva instancia de Modificador, el IDE le mostrará un error:

Ahora podemos usar nuestro Modificador personalizado en nuestra Columna y lograr el mismo resultado que teníamos antes. Tenga en cuenta que ahora podemos cambiar dinámicamente el color de nuestro Círculo:

Column(
    modifier = Modifier.makeColouredCircle(Color.Green),
    horizontalAlignment = Alignment.CenterHorizontally,
    verticalArrangement = Arrangement.Center
) {
    Text("I am text")
    Text("I am text too")
}

Modificadores de interacción

Los modificadores también se pueden usar para agregar interacciones a nuestros Componibles, como hacer que se pueda hacer clic, arrastrar y muchos más. Para ejemplificar esta posibilidad, usaremos un caso de uso muy común: una lista de tarjetas en las que se puede hacer clic que conduce a una página de detalles.

Sugerencia de buenas prácticas: cada vez que cree un Composable, defina un parámetro de Modificador con un Modificador vacío predeterminado. De esta forma podemos flexibilizar nuestros Composables.

@Composable
fun Card(
    modifier: Modifier = Modifier,
    text: String
) {
    Row(
        modifier = modifier
            .border(
                BorderStroke(1.5.dp, color = Color.Black),
                shape = RoundedCornerShape(12.dp)
            )
            .padding(10.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Icon(
            imageVector = Icons.Default.Settings,
            contentDescription = null
        )
        Spacer(Modifier.width(10.dp))
        Text(text = text, modifier = Modifier.fillMaxWidth())
    }
}
Scaffold {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(20.dp),
        verticalArrangement = Arrangement.spacedBy(10.dp)
    ) {
        Card(text = "Card 1", modifier = Modifier.fillMaxWidth())
        Card(text = "Card 2", modifier = Modifier.fillMaxWidth())
        Card(text = "Card 3", modifier = Modifier.fillMaxWidth())
        Card(text = "Card 4", modifier = Modifier.fillMaxWidth())
        Card(text = "Card 5", modifier = Modifier.fillMaxWidth())
    }
}

Este es nuestro diseño base:

Ahora vamos a agregar una devolución de llamada a nuestra Card Composable para que podamos definir qué sucede cuando hacemos clic en ella.

@Composable
fun Card(
    modifier: Modifier = Modifier,
    text: String,
    onClick: () -> Unit
) {
    Row(
        modifier = modifier
            .border(
                BorderStroke(1.5.dp, color = Color.Black),
                shape = RoundedCornerShape(12.dp)
            )
            .clickable {
                onClick()
            }
            .padding(10.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Icon(
            imageVector = Icons.Default.Settings,
            contentDescription = null
        )
        Spacer(Modifier.width(10.dp))
        Text(text = text, modifier = Modifier.fillMaxWidth())
    }
}

Para hacer que se pueda hacer clic en nuestro componible, debemos usar el clickablemodificador, esto permite que el componente reciba eventos de clic o clic de accesibilidad.

Tenga en cuenta que simplemente estamos agregando el onClickparámetro al modificador de nuestro componible, entonces, ¿por qué no eliminar este parámetro y simplemente agregar la propiedad en la que se puede hacer clic directamente en el parámetro del modificador? Bueno, eso es cuestión de legibilidad y buenas prácticas. Al definir explícitamente el onClick parámetro, podemos afirmar que se supone que se puede hacer clic en este composable dado, sin este parámetro, no hay forma de que otros desarrolladores sepan sobre este evento de clic esperado en Card Composable porque, en teoría, cada función componible que tiene un modificador se puede hacer clic en el parámetro si agrega el clickablemodificador a su cadena de modificadores.

Ahora agreguemos un poco de comportamiento para nuestros Card Composables.

Column(
    modifier = Modifier
        .fillMaxSize()
        .padding(20.dp),
    verticalArrangement = Arrangement.spacedBy(10.dp)
) {
    Card(
        text = "Card 1",
        modifier = Modifier.fillMaxWidth(),
        onClick = {
            Log.d("card", "card clicked")
        }
    )
    Card(
        text = "Card 1",
        modifier = Modifier.fillMaxWidth(),
        onClick = {
            Log.d("card", "card clicked")
        }
    )
    Card(
        text = "Card 1",
        modifier = Modifier.fillMaxWidth(),
        onClick = {
            Log.d("card", "card clicked")
        }
    )
    Card(
        text = "Card 1",
        modifier = Modifier.fillMaxWidth(),
        onClick = {
            Log.d("card", "card clicked")
        }
    )
}

¡Listo, ahora se puede hacer clic en las tarjetas!

Referencias

https://developer.android.com/jetpack/compose/modifiers

https://developer.android.com/jetpack/compose/modifiers-list

Fuente: https://betterprogramming.pub/jetpack-compose-understanding-modifiers-part-1-introduction-831582dc067d

#jetpack 

What is GEEK

Buddha Community

Introducción A Los Modificadores De Redacción De Jetpack

Introducción A Los Modificadores De Redacción De Jetpack

Este artículo supone que el lector tiene conocimientos básicos sobre cómo funciona Jetpack Compose, si no está familiarizado con las @Composablefunciones anotadas, le aconsejo que estudie estos temas antes de leer este artículo.

Jetpack Compose es una biblioteca diseñada para traer patrones de IU declarativos al desarrollo de Android.

Es una función innovadora que cambia por completo la forma en que los desarrolladores tienen que pensar y diseñar su interfaz de usuario, dado que hay poco que ver con el (antiguo) sistema de vista XML.

Los Componibles predeterminados (basados ​​en la especificación Material UI) son altamente personalizables de forma predeterminada, pero la existencia de Modificadores aumenta las posibilidades de personalización a más de nueve mil.

Personalización de un componente regular

La mayoría de Composables son personalizables a través de sus parámetros, por ejemplo, podemos cambiar el color y el progreso actual de un CircularProgressBar(), o establecer íconos iniciales/posteriores para TextField()Composables.

Pero en la mayoría de los casos, esto puede no ser suficiente. Las cajas, por ejemplo, no tienen muchas opciones de personalización a través de sus parámetros.

@Composable
inline fun Box(
    modifier: Modifier = Modifier,
    contentAlignment: Alignment = Alignment.TopStart,
    propagateMinConstraints: Boolean = false,
    content: @Composable BoxScope.() -> Unit
)

Gist 1: Parámetros disponibles de Box Composable

Composable Box()no parece un componente muy flexible, dado que no tenemos parámetros explícitos para modificar los colores, la forma, los bordes, la altura, el ancho y muchas otras propiedades útiles para lograr el objetivo de la interfaz de usuario.

Pero la cuestión es que no necesitamos todos estos parámetros simplemente por la existencia de modificadores.

¿Qué es un modificador?

De acuerdo con la documentación de Android, un Modificador es un conjunto encadenado de propiedades que se pueden asignar a un Composable, capaz de modificar el diseño, agregar detectores de eventos y mucho más.

Imagen 1: Algunos de los modificadores disponibles para Box Composable dentro de un Scaffold.

Los modificadores se encadenan usando un patrón de fábrica, por lo que si deseamos establecer el color de fondo del cuadro en amarillo y establecer su altura y ancho, podríamos hacer algo como esto:


Box(
     modifier = Modifier
         .background(Color.Yellow)
         .height(60.dp)
         .width(100.dp)
 )

Gist 2: Colorear una caja y establecer sus dimensiones

Imagen 2: Resultado del código diseñado en Gist 2.

A veces es una cuestión de orden

Al realizar cambios menores en un Composable, el orden de los Modificadores puede no hacer ninguna diferencia, pero cuando se necesita un diseño más complejo, debemos prestar atención al orden de nuestros Modificadores encadenados. Para ejemplificar este uso, codificaremos el diseño a continuación:

Primero, vamos a crear la estructura base de nuestro diseño, con un Scaffold como el "esqueleto" de la pantalla y una caja para envolver nuestro contenido. Tenga en cuenta que ya estamos usando un modificador aquí Modifier.fillMaxSize()para hacer que Box Composable se ajuste al tamaño completo de Scaffold.

Scaffold {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        // Our content will be coded here 
    }
}

Ahora agreguemos nuestros componibles, modificadores y entendamos lo que está pasando aquí:

 Scaffold {
     Box(
         modifier = Modifier.fillMaxSize(),
         contentAlignment = Alignment.Center
     ) {
         Column(
             modifier = Modifier
                 .clip(CircleShape)
                 .fillMaxWidth(0.8f)
                 .aspectRatio(1f)
                 .background(Color.Gray),
             horizontalAlignment = Alignment.CenterHorizontally,
             verticalArrangement = Arrangement.Center
         ) {
             Text("I am text")
             Text("I am text too")
         }
     }
 }

Para lograr este diseño, decidí usar un cuadro como envoltorio de pantalla con el modificador fillMaxSize(), por lo que este mismo componible llenará todo el tamaño de su padre. Como complemento a la caja, utilicé una Columna para que fuera nuestro círculo con los elementos componibles de Texto dentro.

En este orden exacto Modifier, podemos lograr fácilmente el círculo gris con dos textos (uno encima del otro), ahora entendamos qué hace cada uno de los modificadores de la Columna y luego cambiemos su orden para causar que el diseño se rompa a propósito.

  • clip: El modificador de recorte sirve para recortar el Composable para que podamos cambiar fácilmente su forma. Usando este modificador podemos transformar un Box rectangular (la forma predeterminada del Box Composable) en un rectángulo de esquina redondeada o un círculo, por ejemplo.
  • fillMaxWidth: este modificador sirve para informar al componible para que se ajuste al ancho máximo del padre (esto es similar a una vista de ancho de 0dp restringida al inicio y al final de su padre cuando se usa Diseño de restricción). El parámetro de fracción sirve para definir el "peso" de este autorrelleno, por ejemplo, al usar 0.1f llenaremos el 10% del ancho del padre y 1.0f llenará todo el ancho disponible.
  • aspectRatio: Este modificador intentará igualar la altura y el ancho de un componible de acuerdo con el parámetro de proporción. Al usar clip , definimos nuestro componible como un círculo y fillMaxWidth establece que el diámetro de nuestro círculo llenará el 80% del ancho máximo del padre, pero esta solución no dará como resultado un círculo perfecto, al eliminar aspectRatio podemos ver que la columna tiene la forma de un rectángulo de esquinas redondeadas y no un círculo. Esto sucede porque el círculo necesita que la altura y el ancho retengan el mismo valor, por lo que al usar aspectRatio(1)podemos asegurarnos de que nuestro círculo tenga el mismo ancho y alto.

  • backgroundColor: Establece el color de fondo de un componible al valor dado. El backgroundColor es uno de los modificadores en los que importa el orden, y podemos ver este comportamiento si nos movemos backgroundColorantes del clipmodificador. Esto sucede porque esencialmente estamos pintando el componible antes de recortar sus límites, por cuestiones prácticas, nuestra Columna se recorta para ser un Círculo. Pero debido a que lo pintamos antes del recorte, parece que el clipmodificador no funciona, pero lo hace, es solo una cuestión de orden.
Column(
    modifier = Modifier
        .background(Color.Gray)
        .clip(CircleShape)
        .fillMaxWidth(0.8f)
        .aspectRatio(1f),
    horizontalAlignment = Alignment.CenterHorizontally,
    verticalArrangement = Arrangement.Center
) 

Modificadores contenidos en el alcance

La biblioteca Compose Standard ofrece toneladas de modificadores de alcance comunes, en otras palabras, modificadores que están disponibles de forma predeterminada, por lo tanto, independientes del alcance actual.

Pero cada vez que se usan Composables como Columna, Fila y Cuadro, probablemente haya notado que la contentlambda está envuelta dentro de un ámbito, por ejemplo, en las columnas que tenemos ColumnScope:

ColumnScopees una interfaz responsable de establecer la altura de Composable en relación con el tamaño de su contenido (envoltura de contenido de forma predeterminada), y también proporciona un conjunto limitado de modificadores que solo están disponibles dentro de este ámbito: weight, aligny alignBy, esto es lo que yo llamo ámbito- Modificadores retenidos.

Puede leer más sobre los ámbitos y sus respectivos modificadores retenidos accediendo al código fuente a través del IDE o leyendo la documentación oficial.

Si volvemos a nuestro diseño de columna en forma de círculo y agregamos el alignmodificador a nuestros TextComposables, podemos alinearlos horizontalmente en la columna

Estos modificadores de alineación también están disponibles en Row Composable, pero en este caso, son los encargados de alinear el contenido verticalmente dentro de la fila. Esto también es cierto para BoxScope, pero en este caso tenemos modificadores que pueden controlar la posición tanto horizontal como verticalmente.

 Column(
     modifier = Modifier
         .clip(CircleShape)
         .background(Color.Gray)
         .fillMaxWidth(0.8f)
         .aspectRatio(1f),
     horizontalAlignment = Alignment.CenterHorizontally,
     verticalArrangement = Arrangement.Center
 ) {
     Text("I am text", modifier = Modifier.align(Alignment.End))
     Text("I am text too", modifier = Modifier.align(Alignment.Start))
 }

Los cambios anteriores producirán el diseño a continuación, al agregar los alignmodificadores a nuestros Textcomponibles, tenemos control directo de su posición horizontal dentro de la Columna.

Modificadores de recombinación

Los modificadores también se pueden recombinar mediante la creación de un solo modificador que aplique otros modificadores, en nuestro caso, podemos crear uno makeColouredCircleque reciba un parámetro de color.


fun Modifier.makeColouredCircle(color: Color): Modifier =
    this.then(
        Modifier
            .clip(CircleShape)
            .background(color)
            .fillMaxWidth(0.8f)
            .aspectRatio(1f)
    )

Dado que los modificadores se encadenan uno tras otro, debemos garantizar que los agregados previamente no se perderán al aplicar nuestro modificador personalizado, es por eso que debemos usar la this.thendeclaración. La thenfunción sirve para agregar más modificadores a una instancia de modificador preexistente.

En este ejemplo, estamos agregando modificadores de medición en nuestro Modificador personalizado, pero tenga en cuenta que NO ES una buena práctica, por lo general, fillMaxWidth y aspectRatio debe usarse directamente en nuestro Column Composable

No tiene que preocuparse por tener en cuenta esta regla cada vez que cree un nuevo Modificador personalizado, si simplemente intenta devolver una nueva instancia de Modificador, el IDE le mostrará un error:

Ahora podemos usar nuestro Modificador personalizado en nuestra Columna y lograr el mismo resultado que teníamos antes. Tenga en cuenta que ahora podemos cambiar dinámicamente el color de nuestro Círculo:

Column(
    modifier = Modifier.makeColouredCircle(Color.Green),
    horizontalAlignment = Alignment.CenterHorizontally,
    verticalArrangement = Arrangement.Center
) {
    Text("I am text")
    Text("I am text too")
}

Modificadores de interacción

Los modificadores también se pueden usar para agregar interacciones a nuestros Componibles, como hacer que se pueda hacer clic, arrastrar y muchos más. Para ejemplificar esta posibilidad, usaremos un caso de uso muy común: una lista de tarjetas en las que se puede hacer clic que conduce a una página de detalles.

Sugerencia de buenas prácticas: cada vez que cree un Composable, defina un parámetro de Modificador con un Modificador vacío predeterminado. De esta forma podemos flexibilizar nuestros Composables.

@Composable
fun Card(
    modifier: Modifier = Modifier,
    text: String
) {
    Row(
        modifier = modifier
            .border(
                BorderStroke(1.5.dp, color = Color.Black),
                shape = RoundedCornerShape(12.dp)
            )
            .padding(10.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Icon(
            imageVector = Icons.Default.Settings,
            contentDescription = null
        )
        Spacer(Modifier.width(10.dp))
        Text(text = text, modifier = Modifier.fillMaxWidth())
    }
}
Scaffold {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(20.dp),
        verticalArrangement = Arrangement.spacedBy(10.dp)
    ) {
        Card(text = "Card 1", modifier = Modifier.fillMaxWidth())
        Card(text = "Card 2", modifier = Modifier.fillMaxWidth())
        Card(text = "Card 3", modifier = Modifier.fillMaxWidth())
        Card(text = "Card 4", modifier = Modifier.fillMaxWidth())
        Card(text = "Card 5", modifier = Modifier.fillMaxWidth())
    }
}

Este es nuestro diseño base:

Ahora vamos a agregar una devolución de llamada a nuestra Card Composable para que podamos definir qué sucede cuando hacemos clic en ella.

@Composable
fun Card(
    modifier: Modifier = Modifier,
    text: String,
    onClick: () -> Unit
) {
    Row(
        modifier = modifier
            .border(
                BorderStroke(1.5.dp, color = Color.Black),
                shape = RoundedCornerShape(12.dp)
            )
            .clickable {
                onClick()
            }
            .padding(10.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Icon(
            imageVector = Icons.Default.Settings,
            contentDescription = null
        )
        Spacer(Modifier.width(10.dp))
        Text(text = text, modifier = Modifier.fillMaxWidth())
    }
}

Para hacer que se pueda hacer clic en nuestro componible, debemos usar el clickablemodificador, esto permite que el componente reciba eventos de clic o clic de accesibilidad.

Tenga en cuenta que simplemente estamos agregando el onClickparámetro al modificador de nuestro componible, entonces, ¿por qué no eliminar este parámetro y simplemente agregar la propiedad en la que se puede hacer clic directamente en el parámetro del modificador? Bueno, eso es cuestión de legibilidad y buenas prácticas. Al definir explícitamente el onClick parámetro, podemos afirmar que se supone que se puede hacer clic en este composable dado, sin este parámetro, no hay forma de que otros desarrolladores sepan sobre este evento de clic esperado en Card Composable porque, en teoría, cada función componible que tiene un modificador se puede hacer clic en el parámetro si agrega el clickablemodificador a su cadena de modificadores.

Ahora agreguemos un poco de comportamiento para nuestros Card Composables.

Column(
    modifier = Modifier
        .fillMaxSize()
        .padding(20.dp),
    verticalArrangement = Arrangement.spacedBy(10.dp)
) {
    Card(
        text = "Card 1",
        modifier = Modifier.fillMaxWidth(),
        onClick = {
            Log.d("card", "card clicked")
        }
    )
    Card(
        text = "Card 1",
        modifier = Modifier.fillMaxWidth(),
        onClick = {
            Log.d("card", "card clicked")
        }
    )
    Card(
        text = "Card 1",
        modifier = Modifier.fillMaxWidth(),
        onClick = {
            Log.d("card", "card clicked")
        }
    )
    Card(
        text = "Card 1",
        modifier = Modifier.fillMaxWidth(),
        onClick = {
            Log.d("card", "card clicked")
        }
    )
}

¡Listo, ahora se puede hacer clic en las tarjetas!

Referencias

https://developer.android.com/jetpack/compose/modifiers

https://developer.android.com/jetpack/compose/modifiers-list

Fuente: https://betterprogramming.pub/jetpack-compose-understanding-modifiers-part-1-introduction-831582dc067d

#jetpack 

joe biden

1617255938

¿Cómo migrar los buzones de correo de Exchange a la nube de Office 365?

Si tiene problemas para migrar los buzones de correo de Exchange a Office 365, debe leer este artículo para saber cómo migrar los buzones de correo de Exchange EDB a Office 365. Al migrar a Office 365, los usuarios pueden acceder a sus buzones de correo desde cualquier lugar y desde cualquier dispositivo.

En esta publicación, explicaremos las razones detrás de esta migración y una solución profesional para migrar de Exchange a Office 365.

Razones para migrar Exchange Server a la nube de Office 365

Office 365 apareció por primera vez en 2011 y, dado que se considera la mejor plataforma para aquellas organizaciones que desean administrar todo su sistema de correo electrónico en la nube. Estas son las características clave de Office 365:

  1. Permite trabajar desde cualquier lugar y desde cualquier lugar.
  2. No se preocupe por el spam y el malware.
  3. La seguridad proporcionada por Office 365 es altamente confiable.
  4. Controla el costo total y brinda flexibilidad financiera.
  5. Todas las actualizaciones y mejoras son administradas por Microsoft.

¿Cómo migrar los buzones de correo de Exchange a Office 365?

Hay varias formas manuales de migrar los buzones de correo de Exchange EDB a Office 365, pero para evitar estos complicados y prolongados procedimientos, presentamos una solución de terceros, es decir, la herramienta de migración de Exchange, que es automatizada y directa para la migración de Exchange a Office 365. La herramienta funciona rápidamente y migra todos los elementos del buzón de Exchange Server a Office 365.

La herramienta de migración de Datavare Exchange es demasiado fácil de usar y ofrece pasos sencillos para migrar EDB a Office 365:

  1. Descargue e instale el software en su sistema.
  2. Agregue el archivo EDB de Exchange con el botón Examinar.
  3. Seleccione exportar a buzones de correo de Office 365.
  4. Proporcione los detalles de inicio de sesión de la cuenta de Office 365.
  5. Seleccione la carpeta y presione el botón Finalizar.

Por lo tanto, todos sus buzones de correo de Exchange EDB ahora se migran a Office 365.
Nota: puede usar filtros para migrar los elementos de datos deseados de la cuenta de Exchange a la de Office 365

Líneas finales

Este blog le indica una solución profesional para la migración de buzones de correo de Exchange a la cuenta de Office 365. Dado que las soluciones manuales son complicadas, sugerimos la herramienta de migración de Exchange, que es demasiado simple de usar. Los usuarios no se enfrentan a problemas al operar el programa. La mejor parte de este software es que no necesita habilidades técnicas para realizar la migración. Se puede comprender el funcionamiento del software descargando la versión de demostración que permite la migración de los primeros 50 elementos por carpeta.

Más información:- https://www.datavare.com/software/edb-migration.html

#herramienta de migración de intercambio #migración de intercambio #migrar buzones de correo de exchange

joe biden

1617257581

Software de restauración de Exchange para restaurar sin problemas PST en Exchange Server

¿Quiere restaurar los buzones de correo de PST a Exchange Server? Entonces, estás en la página correcta. Aquí, lo guiaremos sobre cómo puede restaurar fácilmente mensajes y otros elementos de PST a MS Exchange Server.

Muchas veces, los usuarios necesitan restaurar los elementos de datos de PST en Exchange Server, pero debido a la falta de disponibilidad de una solución confiable, los usuarios no pueden obtener la solución. Háganos saber primero sobre el archivo PST y MS Exchange Server.

Conozca PST y Exchange Server

PST es un formato de archivo utilizado por MS Outlook, un cliente de correo electrónico de Windows y muy popular entre los usuarios domésticos y comerciales.

Por otro lado, Exchange Server es un poderoso servidor de correo electrónico donde todos los datos se almacenan en un archivo EDB. Los usuarios generalmente guardan la copia de seguridad de los buzones de correo de Exchange en el archivo PST, pero muchas veces, los usuarios deben restaurar los datos del archivo PST en Exchange. Para resolver este problema, estamos aquí con una solución profesional que discutiremos en la siguiente sección de esta publicación.

Un método profesional para restaurar PST a Exchange Server

No le recomendamos que elija una solución al azar para restaurar los datos de PST en Exchange Server. Por lo tanto, al realizar varias investigaciones, estamos aquí con una solución inteligente y conveniente, es decir, Exchange Restore Software. Es demasiado fácil de manejar por todos los usuarios y restaurar cómodamente todos los datos del archivo PST a Exchange Server.

Funciones principales ofrecidas por Exchange Restore Software

El software es demasiado simple de usar y se puede instalar fácilmente en todas las versiones de Windows. Con unos pocos clics, la herramienta puede restaurar los elementos del buzón de Exchange.

No es necesario que MS Outlook restaure los datos PST en Exchange. Todos los correos electrónicos, contactos, notas, calendarios, etc. se restauran desde el archivo PST a Exchange Server.

Todas las versiones de Outlook son compatibles con la herramienta, como Outlook 2019, 2016, 2013, 2010, 2007, etc. La herramienta proporciona varios filtros mediante los cuales se pueden restaurar los datos deseados desde un archivo PST a Exchange Server. El programa se puede instalar en todas las versiones de Windows como Windows 10, 8.1, 8, 7, XP, Vista, etc.

Descargue la versión de demostración del software de restauración de Exchange y analice el funcionamiento del software restaurando los primeros 50 elementos por carpeta.

Líneas finales

No existe una solución manual para restaurar los buzones de correo de Exchange desde el archivo PST. Por lo tanto, hemos explicado una solución fácil e inteligente para restaurar datos de archivos PST en Exchange Server. Simplemente puede usar este software y restaurar todos los datos de PST a Exchange Server.

Más información:- https://www.datavare.com/software/exchange-restore.html

#intercambio de software de restauración #intercambio de restauración #buzón del servidor de intercambio #herramienta de restauración de intercambio

Top 10+ iPhone App Development Companies in Los Angeles 2020 – TopDevelopers.co

Profusely examined top iPhone App Development companies in Los Angeles with ratings & reviews to help find the best iPhone App Developers to build your solution.

#iphone app development service providers in los angeles #top iphone app development companies in los angeles #best iphone app developers at los angeles #hire iphone app developers los angeles #los angeles #expert iphone app developers

Best iOS / iPhone App Developers in Los Angeles

Looking for a top iPhone app development company? You want to make certain you build an excellent client community with application development technology that sees you as a talker of all trends in the industry. Failure to navigate the iPhone app wave will get you into trouble.

AppClues Infotech is the fastest rising iPhone application development company in Los Angeles, with a strong team of top experts providing custom iOS application development services that provide cost-effective solutions. We offer total turnkey solutions for those who want to turn their iPhone app ideas into actuality.

Our Services:

  • iPhone Application Development
  • iPhone/iPad Games Development
  • iPhone Application Code Check
  • iPhone Social Media Applications
  • iPhone Application Testing Services
  • iPhone Widget Development
  • Custom iPhone Application Development
  • iPhone Application Support
  • Maintenance & Optimization
  • Migration and Porting
  • Wearable Integration

Get high-performance and scalable, enterprise-ready iPhone application solutions based on the exact needs and desires of your business. Contact us today and let us talk about how we can assist you to build your online visibility a huge achievement.

For more info:
Website: https://www.appcluesinfotech.com/
Email: info@appcluesinfotech.com
Call: +1-978-309-9910

#app developers in los angeles #los angeles app development #top ios app development company #top mobile app development company in los angeles #mobile app development company in los angeles #iphone app development company los angeles