Saltearse al contenido

Control del renderizado

En Flutter, el control eficiente del renderizado es crucial para crear aplicaciones de alto rendimiento, receptivas y escalables. El paquete flutter_reactter ofrece una manera sencilla de gestionar el comportamiento del renderizado en el árbol de widgets, permitiendo optimizar el rendimiento y ajustar la capacidad de respuesta de la aplicación con facilidad.

API

Este paquete proporciona los siguientes mecanismos de control del renderizado:

How it works

El control del renderizado en Reactter se basa en dos conceptos fundamentales de Flutter:

  • InheritedWidget: Este mecanismo poderoso comparte eficientemente datos en todo el árbol de widgets. Reactter extiende esta capacidad con el widget RtProvider , que almacena dependencias utilizando el sistema de inyección de dependencias. Esto permite que los widgets descendientes accedan a estas dependencias según sea necesario.

  • Extensiones de BuildContext: Estos métodos facilitan el acceso a dependencias y el control del renderizado dentro del árbol de widgets. Los widgets de Reactter como RtConsumer , RtSelector y RtComponent utilizan estos métodos para observar dependencias o estados. Cuando la dependencia o cualquier estado observado cambia, estos widgets activan rápidamente la reconstrucción del árbol de widgets para reflejar el estado actualizado.

Ejemplo

Veamos cómo crear una aplicación de contador simple usando Reactter para demostrar cómo controlar el renderizado del árbol de widgets en Flutter.

1
import 'package:flutter/material.dart';
2
import 'package:flutter_reactter/flutter_reactter.dart';
3
import 'counter_controller.dart';
4
5
class Counter extends StatelessWidget {
6
const Counter({Key? key}) : super(key: key);
7
8
@override
9
Widget build(BuildContext context) {
10
// Provide the `CounterController` dependency to the widget tree
11
return RtProvider<CounterController>(
12
() => CounterController(),
13
builder: (context, counterController, child) {
14
return Row(
15
mainAxisSize: MainAxisSize.min,
16
children: [
17
ElevatedButton(
18
onPressed: counterController.decrement,
19
child: const Icon(Icons.remove),
20
),
21
const SizedBox(width: 8),
22
// Observe the `count` property of the `counterController`
23
// and rebuild the widget tree when the `count` value changes
24
RtConsumer<CounterController>(
25
listenStates: (counterController) => [counterController.count],
26
builder: (context, counterController, child) {
27
return Text("${counterController.count}");
28
},
29
),
30
const SizedBox(width: 8),
31
ElevatedButton(
32
onPressed: counterController.increment,
33
child: const Icon(Icons.add),
34
),
35
],
36
);
37
},
38
);
39
}
40
}
1
import 'package:reactter/reactter.dart';
2
3
class CounterController {
4
// Create a reactive state using the `Signal` class
5
final count = Signal(0);
6
7
void increment() {
8
count.value++;
9
}
10
11
void decrement() {
12
count.value--;
13
}
14
}
1
import 'package:flutter/material.dart';
2
import 'counter.dart';
3
4
class CounterView extends StatelessWidget {
5
const CounterView({Key? key}) : super(key: key);
6
7
@override
8
Widget build(BuildContext context) {
9
return Scaffold(
10
appBar: AppBar(
11
title: const Text("Counter"),
12
),
13
body: const Center(
14
child: Counter(),
15
),
16
);
17
}
18
}
1
import 'package:flutter/material.dart';
2
import 'counter_view.dart';
3
4
void main() {
5
runApp(MyApp());
6
}
7
8
class MyApp extends StatelessWidget {
9
@override
10
Widget build(BuildContext context) {
11
return MaterialApp(
12
home: CounterView(),
13
);
14
}
15
}

Ahora, cuando ejecutes la aplicación, verás una aplicación de contador con dos botones para incrementar y decrementar el valor de count.

En este caso, solo el widget Text se reconstruirá cuando el valor de count cambie, mientras que el widget CounterView no se reconstruirá por completo. Esto se debe a que el widget RtConsumer observa la propiedad count y activa la reconstrucción del árbol de widgets únicamente cuando el valor de count cambia.

En el ejemplo anterior, utilizamos el widget RtConsumer para observar la propiedad count de la instancia counterController, pero podemos lograr la misma funcionalidad utilizando el método watch de la clase BuildContext .

A continuación, mostramos cómo modificar el código para emplear el método watch junto al widget Builder y lograr el mismo resultado:

counter_view.dart
23
// Observe the `count` property of the `counterController`
24
// and rebuild the widget tree when the `count` value changes
25
RtConsumer<CounterController>(
26
listenStates: (counterController) => [counterController.count],
27
builder: (context, counterController, child) {
28
Builder(
29
builder: (context) {
30
// Observe the `count` property of the `counterController`
31
// and rebuild the widget tree when the `count` value changes
32
final counterController = context.watch<CounterController>(
33
(counterController) => [counterController.count],
34
);
35
36
return Text("${counterController.count}");
37
},
38
),

Mientras que el método watch puede emplearse directamente dentro del método builder del widget RtProvider , es aconsejable utilizarlo junto a un widget Builder para evitar reconstrucciones innecesarias del árbol de widgets. Esta práctica aprovecha el alcance de BuildContext , ofreciendo un enfoque más granular para controlar el renderizado dentro del árbol de widgets.

Para casos de uso más avanzados, puedes emplear otros widgets de Reactter y métodos de BuildContext para poder refinar aún más el control del renderizado del árbol de widgets.