# Viniendo de Flutter

> Tabla Widget→Component completa y ejemplos "cómo era / cómo queda" para quienes vienen de Flutter.

Source: https://crossfly.dev/es/docs/migrate/from-flutter — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Viniendo de Flutter

Flutter es el par filosófico más cercano a CrossFly — **ambos renderizan vía GPU, sin widgets
nativos**, por lo que la apariencia es idéntica en todas las plataformas. La diferencia es el modelo: Flutter
**reconstruye** a partir del estado; en CrossFly tú **mutas objetos**. Lee primero
[la filosofía](/docs/migrate/overview).

## Tabla de traducción
| Flutter | CrossFly |
|---|---|
| `Widget` | `Component` |
| `StatelessWidget` / `StatefulWidget` | subclase de `Component` / `Window` |
| `build(context)` | `onShow()` (montar) / `onPaint()` (dibujar) |
| `setState(() => ...)` | mutar campo + `repaint()` (+ `setValidLayout(false)` si cambió el tamaño) |
| `Scaffold` | `Window` (+ `TabBar` para pestañas) |
| `Navigator.push` / `pop` | `window.show()` / `hide()` |
| `Column` / `Row` | `VerticalLayout` / `HorizontalLayout` |
| `Expanded` / `Flexible` | `add(LAY_FILL, c)` (`-1f`) |
| `Padding` | `ingap` en el estilo (`ComponentStyle`) |
| `SizedBox` / `Spacer` | `Gap` / fracciones en el layout |
| `ListView.builder` | `VirtualListView` |
| `Text` | `Label` |
| `ElevatedButton` / `TextButton` | `Button` |
| `TextField` | `TextField` |
| `showDialog` / `AlertDialog` | `Alert` |
| `SnackBar` / `Tooltip` | `Hint` |
| `Theme` / `ThemeData` | `Theme` / `ColorScheme` / `Skin` |
| `Future` / `async` / `await` | `Thread` + `Component.onUI(...)` |
| `Color(0xFF2196F3)` | `int 0xFF2196F3` (`UIConstants` / `ColorUtils`) |
| `shared_preferences` | **sin equivalente** → SQLite ([guía](/docs/data-and-services/files-and-preferences)) |

### Botón con acción
```dart
// Flutter
ElevatedButton(onPressed: salvar, child: Text("Salvar"))
```
```java
// CrossFly
new Button("Salvar").onAction(c -> salvar());
```

### Pantalla con lista
```dart
// Flutter
ListView.builder(itemCount: itens.length,
   itemBuilder: (ctx, i) => ListTile(title: Text(itens[i].nome)));
```
```java
// CrossFly — virtualizado, montado en onShow()
VirtualListView lista = new VirtualListView(Relative.ofFont(3f), new DataAdapter() {
   public int getCount() { return itens.size(); }
   public Component createView() { return new Label(""); }
   public void bindView(Component v, int i) { ((Label) v).setText(itens.get(i).nome); }
});
add(LAY_FILL, lista);
```

### Diálogo de confirmación
```dart
// Flutter
showDialog(context: ctx, builder: (_) => AlertDialog(
   title: Text("Excluir"), content: Text("Confirma?"),
   actions: [ TextButton(onPressed: excluir, child: Text("Excluir")) ]));
```
```java
// CrossFly — textos en el constructor; acción por índice
Alert a = new Alert("Excluir", "Confirma?", "Cancelar", "Excluir");
a.buttonAction(1, c -> excluir());
a.show();
```

## Buenas prácticas en la transición
- Donde harías `setState`, haz **mutación + `repaint()`** — guarda la referencia del widget.
- Donde había `FutureBuilder`/`async`, usa **`Thread` + `Component.onUI`** (ver [background](/docs/data-and-services/background-work)).
- `Expanded` se vuelve `LAY_FILL`; `Padding` se vuelve `ingap` en el estilo.

## Véase también
- [Get Started](/docs/get-started) · [Layouts](/docs/ui/layouts) · [Navegación](/docs/ui/navigation)
