Flutter-Widgets: Unterschied zwischen den Versionen
Zeile 55: | Zeile 55: | ||
</pre> | </pre> | ||
= Formular = | = Abwandlungen = | ||
== Visibility == | |||
Damit kann die Sichtbarkeit eines Elements gesteuert werden. Ganz wichtig für GetX-Layouts! | |||
Im folgenden Beispiel wird entweder das eine oder das andere Element angezeigt. | |||
<pre> | |||
final widgets = <Widget>[ | |||
Visibility( | |||
visible: controller.isEmpty.value, | |||
child: buildEmptyImage() | |||
), | |||
Visibility( | |||
visible: !controller.isEmpty.value, | |||
child: buildImage() | |||
), | |||
]; | |||
</pre> | |||
== Tooltip == | |||
Dieses Element erzeugt einen Erklärungstext, der erscheint, wenn die Maus kurz auf dem Kindelement verweilt. | |||
<pre> | |||
final widget = Tooltip( | |||
message: 'Löschen', | |||
child: Icon(Icons.delete_forever_outlined) | |||
); | |||
</pre> | |||
== Inkwell (Reaktionsfläche) == | |||
Mit diesem Element ist es möglich, eine Aktion zu definieren, wenn das Kindelement berührt/angeklickt wird. | |||
<pre> | |||
final Widget = Material( | |||
color: Colors.green, | |||
child: InkWell( | |||
onTap: () async { Get.toNamed(Routes.routeAction); } | |||
child: SizedBox(width: 200, height: 200, child: image.value,), | |||
), | |||
); | |||
</pre> | |||
= Formular (Text und Dropdown) = | |||
Jedes Formular benötigt einen '''Key''', der normalerweise im Controller erzeugt/gespeichert wird: | Jedes Formular benötigt einen '''Key''', der normalerweise im Controller erzeugt/gespeichert wird: | ||
Aktuelle Version vom 27. September 2022, 05:06 Uhr
Links[Bearbeiten]
Häufige Widgets[Bearbeiten]
Column / Row[Bearbeiten]
Ein Container, in dem die Unterelemente senkrecht (Column) oder waagrecht (Row) angeordnet werden. Die Unterelemente bestimmen
List<Widget> = [ Col( crossAxisAlignment: CrossAxisAlignment.start, children = [ Row( children: [ Expanded( child: const Text('Be surprised!'), ), const SizedBox(width: 16), ElevatedButton( child: Text('Click it'), onPressed: () => sayHello(), ), ]), const SizedBox(height: 16), Row( children: [ const Expanded (flex: 7, child: Text('You need help?'), ), const SizedBox(height: padding), const Expanded (flex: 2, child: ElevatedButton( child: Text('Help me'), onPressed: () => help(), ), ), ]), ]), ];
Platzverteilung[Bearbeiten]
Normalerweise bestimmen die Unterelemente (children
) die Dimensionen, sie werden einfach untereinander / hintereinander positioniert.
Will man eine automatische Anpassung, werden die "dynamischen" Elemente jeweils in ein Expanded-Element eingebettet.
In diesem Fall wird der Restplatz an alle dynamischen Elemente gleichmäßig verteilt. Mit dem Parameter flex
von Expanded kann das Verhältnis eingestellt werden.
Card[Bearbeiten]
final widget = Card( margin: EdgeInsets.symmetric(vertical: 16.0, horizontal: 16.0), child: Padding( padding: EdgeInsets.symmetric(vertical: 16.0, horizontal: 16.0), child: Text('Wow!'), ), );
Abwandlungen[Bearbeiten]
Visibility[Bearbeiten]
Damit kann die Sichtbarkeit eines Elements gesteuert werden. Ganz wichtig für GetX-Layouts!
Im folgenden Beispiel wird entweder das eine oder das andere Element angezeigt.
final widgets = <Widget>[ Visibility( visible: controller.isEmpty.value, child: buildEmptyImage() ), Visibility( visible: !controller.isEmpty.value, child: buildImage() ), ];
Tooltip[Bearbeiten]
Dieses Element erzeugt einen Erklärungstext, der erscheint, wenn die Maus kurz auf dem Kindelement verweilt.
final widget = Tooltip( message: 'Löschen', child: Icon(Icons.delete_forever_outlined) );
Inkwell (Reaktionsfläche)[Bearbeiten]
Mit diesem Element ist es möglich, eine Aktion zu definieren, wenn das Kindelement berührt/angeklickt wird.
final Widget = Material( color: Colors.green, child: InkWell( onTap: () async { Get.toNamed(Routes.routeAction); } child: SizedBox(width: 200, height: 200, child: image.value,), ), );
Formular (Text und Dropdown)[Bearbeiten]
Jedes Formular benötigt einen Key, der normalerweise im Controller erzeugt/gespeichert wird:
key = GlobalKey<FormState>(debugLabel: 'MyForm');
Ein Formular bietet die Möglichkeit der Eingabeprüfung (Validierung).
- Dazu wird für jedes Formularfeld eine (eventuell anonyme) Funktion angegeben, die im Fehlerfall einen Fehlertext zurückgibt, sonst
null
. - Außerdem hat das Formularfeld einen Parameter
onSave
, der eine Funktion entgegennimmt, die das Speichern des Wertes übernimmt. - Die Validierung wird normalerweise beim Anklicken eines Buttons angestoßen: Alle Textfelder werden validiert.
- Ist die Validierung erfolgreich, wird
formKey.currentKey.store()
aufgerufen. - Dies löst bei allen Textfeldern den Aufruf der Parameterfunktion
onSave
auf.
final items = [ DropdownMenuItem<bool>(value: false, child: Text('inaktive)), DropdownMenuItem<bool>(value: true, child: Text('active)) ]; final form = Form( key: controller.formKey, child: Column( children: [ TextFormField( decoration: InputDecoration(labelText: 'Age'), validator: checkInt, onSaved: (input) => controller.age.value = input, controller: controller.controllerAge, ), DropdownButtonFormField<bool>( value: fieldData.locationId, items: items, isExpanded: true, decoration: const InputDecoration(labelText: 'Status'), onSaved: (value) => controller.status.value = value, ), ]), ); String? checkInt(String input) int.parseInt(input) == null ? 'Not an integer' : null; void store(controller, String input){ if (controller, formKey.currentState?.validate() ?? false) { controller.formKey.currentState?.save(); } }
DropDownButton (Combobox)[Bearbeiten]
final items1 = [ DropdownMenuItem(child: Image.asset('img/undefined.png'), value: ''), DropdownMenuItem(child: Text('Active'), value: 'A'), DropdownMenuItem(child: Text('Inactive'), value: 'I'), ]; final button1 = DropdownButton<String>( value: '', items: items1, onChanged: (value) { controller.active = value }, ); final item2 = List<int>generate(5, (i) => i+1).map((no) => DropdownMenuItem(child: Text('Element $no'), value: no)); final button2 = DropdownButton<int>( value: 0, items: items2, onChanged: (value) { controller.no = value }, );
DropDownField[Bearbeiten]
import 'package:dropdown_textfield/dropdown_textfield.dart'; ... final widget = DropDownTextField( // initialValue: "name4", controller: controller.nameController, clearOption: false, enableSearch: true, searchDecoration: const InputDecoration(hintText: "Type part of the name"), validator: (value) value != null ? null : "Required field", dropDownItemCount: 6, dropDownList: const [ DropDownValueModel(name: 'name1', value: "value1"), DropDownValueModel(name: 'name2', value: "value2", toolTipMsg: "Select an item from the list"), DropDownValueModel(name: 'name3', value: "value3"), DropDownValueModel(name: 'name4', value: "value4", toolTipMsg: "This is value4", ], onChanged: (val) { controller.selectedName = val; }, );
Rückgabe der GetView.build() Methode[Bearbeiten]
Widget build(BuildContext context) { return Scaffold( appBar: controller.applicationData.appBarBuilder('Demo'), drawer: controller.applicationData.drawerBuilder(context), body: Text('Hello world!'), }
Grundgerüst einer GUI-App[Bearbeiten]
void main() { globalLogger = GetxLogger(); ApplicationData.createDummy(); runApp( GetMaterialApp( title: "MyApp", initialRoute: AppPages.initialRoute, getPages: AppPages.routes, ), ); }