Jetpack Compose - Interfaz de chat
prefacio
En la actualidad, la interfaz de usuario declarativa se ha convertido en la tendencia del desarrollo front-end. Además del desarrollo cruzado inicial de React, Flutter, etc. y el soporte web, las plataformas Android e IOS posteriores también han lanzado el desarrollo declarativo. Android se desarrolla a través de Las potentes funciones de lenguaje de Jetpack Compose y Kotlin eliminan por completo el uso imperativo de archivos XML para el diseño de la interfaz de usuario.
efecto de vídeo
Android Jetpack: una interfaz de chat sencilla
introducir
Antes del análisis de código, presente varios diseños comunes
Fila
horizontal
Similar a la disposición de LinearLayout en Android , es consistente con Flutter's Row.
El modificador básicamente realiza la mayor parte del trabajo de configuración de un componente. Implementa una serie de funciones de extensión internamente y realiza then
llamadas en cadena a través de funciones. verticalAlignment
El atributo es la alineación vertical y horizontalArrangement
la alineación horizontal .
Row(
modifier = Modifier.padding(all = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
//some sub views
}
Columna
Excepto por la disposición de Columna y Fila, el resto es más o menos igual, similar a la vertical
disposición de LinearLayout
Column(
modifier = Modifier.weight(1f),
horizontalAlignment = Alignment.End
){
//some sub views
}
Texto
Cuadro de texto, similar a Android TextView
, text
el atributo es el contenido del texto, color
el atributo es el color del texto, style
el atributo es el estilo del texto, puede configurar el tamaño del texto, si está en negrita, el estilo, etc., el sistema tiene muchos estilos incorporados, y el textAlign
atributo es la alineación del texto
Text(
text = msg.author,
color = MaterialTheme.colorScheme.secondary,
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Right
)
Imagen
Equivalente a Android ImageView
, painter
puede configurar directamente la dirección de la imagen (dibujable) a través de PainterResource, y modifier
podemos modificar directamente los atributos de la imagen, como esquinas redondeadas, bordes y tamaño a través de atributos, por lo que no es necesario crear un archivo xml para configurar
Image(
painter = painterResource(id = msg.img),
contentDescription = "",
modifier = Modifier
.size(40.dp)
.clickable { CircleShape }
.border(1.dp, MaterialTheme.colorScheme.secondary, CircleShape)
)
interfaz de chat
Al LazyColumn
implementar una lista vertical, los datos son datos fijos y los subíndices se ubican en los extremos izquierdo y derecho del diseño, y luego el texto predeterminado muestra una línea. Después de hacer clic en la línea de texto, el contenido del texto se expandirá. y su color de fondo será cambiado. Esta demostración adaptada de la versión oficial
Efecto
diseño izquierdo
Solo al agregar @Composable
anotaciones se puede usar la interfaz de usuario declarativa. La interfaz de usuario declarativa adopta una estructura de árbol. En este ejemplo, Fila es el nodo raíz del árbol y tiene dos nodos secundarios, a saber, y (se omite el marcador de posición de espacio en el medio Image
) Column
, y luego Column
It también tiene dos nodos secundarios, a saber, Surface
y Text
, que Surface
tiene otro Text
nodo secundario.
Supervise si se hace clic en una fila y luego realice la modificación de fondo principalmente a través de lo siguiente, que es equivalente al modo observador, controle isExpanded
el campo y luego cambie, es similar al observador inmediatamente. La explicación oficial es la siguiente:
重组:可组合函数可以使用 remember 将本地状态存储在内存中,并跟踪传递给 mutableStateOf 的值的变化。
该值更新时,系统会自动重新绘制使用此状态的可组合项(及其子项)
通过使用 Compose 的状态 API(如 remember 和 mutableStateOf),系统会在状态发生任何变化时自动更新界面。
//监听isExpanded字段
var isExpanded by remember { mutableStateOf(false) }
//收缩和扩展对应俩种颜色,由isExpanded字段决定
val surfaceColor by animateColorAsState(
targetValue = if (isExpanded)
Color.Cyan
else
MaterialTheme.colorScheme.surface
)
Finalmente, modifier = Modifier .clickable { isExpanded = !isExpanded }
agréguelo Cada clic cambiará su valor y luego obtendrá el nodo del valor para volver a dibujar y actualizar
@Composable
fun MessageLeft(msg : Message){
Row(
modifier = Modifier.padding(all = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start) {
//图像
Image(
painter = painterResource(id = msg.img),
contentDescription = "",
modifier = Modifier
.size(40.dp)//图像大小
.clip(CircleShape)
.border(1.dp, MaterialTheme.colorScheme.secondary, CircleShape)
)
//左右间隔
Spacer(modifier = Modifier.width(10.dp))
//重组:可组合函数可以使用 remember 将本地状态存储在内存中,并跟踪传递给 mutableStateOf 的值的变化。
// 该值更新时,系统会自动重新绘制使用此状态的可组合项(及其子项)
//通过使用 Compose 的状态 API(如 remember 和 mutableStateOf),系统会在状态发生任何变化时自动更新界面。
var isExpanded by remember { mutableStateOf(false) }
val surfaceColor by animateColorAsState(
targetValue = if (isExpanded)
Color.Cyan
else
MaterialTheme.colorScheme.surface
)
Column() {
Text(
text = msg.author,
color = MaterialTheme.colorScheme.secondary,
style = MaterialTheme.typography.bodySmall
)
//上下间隔
Spacer(modifier = Modifier.height(10.dp))
Surface(
shape = RectangleShape,
shadowElevation = 1.dp,
tonalElevation = 1.dp,
color = surfaceColor,
modifier = Modifier
.animateContentSize()
.padding(1.dp)
) {
Text(
text = msg.content,
modifier = Modifier
.clickable { isExpanded = !isExpanded }
.padding(all = 4.dp),
maxLines = if (isExpanded) Int.MAX_VALUE else 1,
style = MaterialTheme.typography.bodyMedium,
overflow = TextOverflow.Ellipsis
)
}
}
}
}
diseño correcto
El lado derecho es similar al lado izquierdo, la diferencia es que se cambia horizontalArrangement
la disposición para que quede del lado derecho, y luego se agrega un atributo de peso al texto modifier = Modifier.weight(1f),
para evitar que la línea tenga demasiado contenido y exprimir el imagen derecha fuera de la pantalla
@Composable
fun MessageRight(msg: Message){
Row(
modifier = Modifier
.padding(10.dp)
.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.End) {
//给左边文字一个权重,避免文字过多,让右边图像无法显示
Column(
modifier = Modifier.weight(1f),
horizontalAlignment = Alignment.End
) {
Text(
text = msg.author,
color = MaterialTheme.colorScheme.secondary,
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Right
)
Spacer(modifier = Modifier.height(10.dp))
var isExpanded by remember { mutableStateOf(false) }
val surfaceColor by animateColorAsState(
targetValue = if (isExpanded)
Color.Green
else
MaterialTheme.colorScheme.surface
)
Surface(
shape = RectangleShape,
shadowElevation = 1.dp,
tonalElevation = 1.dp,
color = surfaceColor,
modifier = Modifier
.animateContentSize()
.padding(1.dp)
) {
Text(
text = msg.content,
modifier = Modifier
.clickable { isExpanded = !isExpanded }
.padding(all = 4.dp),
maxLines = if (isExpanded) Int.MAX_VALUE else 1,
style = MaterialTheme.typography.bodyMedium,
overflow = TextOverflow.Ellipsis
)
}
}
Spacer(modifier = Modifier.width(10.dp))
Image(
painter = painterResource(id = msg.img),
contentDescription = "",
modifier = Modifier
.size(40.dp)
.clickable { CircleShape }
.border(1.dp, MaterialTheme.colorScheme.secondary, CircleShape)
)
}
}
insertar datos
¿Es equivalente a Android XML RecyclerView
, es muy simple, no es necesario escribir Adapter
y subelementar archivos XMl y muchas interfaces o algo así?
@Composable
fun ShowMessage(msgList: List<Message>){
//竖向列表
LazyColumn{
itemsIndexed(items = msgList){
index, item ->
if (index %2 == 0)
MessageLeft(msg = item)
else
MessageRight(msg = item)
}
}
}
Resumir
Es posible que la interfaz de usuario declarativa de Jetpack Compose no se use al principio, pero después de acostumbrarse, despegará directamente, mejorando en gran medida la eficiencia del desarrollo y reduciendo el tiempo de desarrollo, y la mayoría de los front-end usan la interfaz de usuario declarativa. Flutter, los dos son básicamente similares en términos de interfaz de usuario, excepto que Flutter se divide en tres partes , y , a través Widget
del anidamiento , y juzga si el nodo es modificado por y , para juzgar si necesita ser redibujado. Finalmente, les sugiero a los desarrolladores de Android que lo usen. Android Jetpack Compose ha estado disponible durante casi un año y es gradualmente estable.Widget
Element
RenderObject
runtimetype
key