Flutter-Widgets: Unterschied zwischen den Versionen

Aus Info-Theke
Zur Navigation springen Zur Suche springen
 
(2 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
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:


Zeile 69: Zeile 108:


<pre>
<pre>
final items = [
  DropdownMenuItem<bool>(value: false, child: Text('inaktive)),
  DropdownMenuItem<bool>(value: true, child: Text('active))
];
final form = Form(
final form = Form(
   key: controller.formKey,
   key: controller.formKey,
Zeile 74: Zeile 117:
     children: [
     children: [
       TextFormField(
       TextFormField(
         decoration: InputDecoration(labelText: 'Data'),
         decoration: InputDecoration(labelText: 'Age'),
         validator: checkInt,
         validator: checkInt,
         onSaved: (input) => controller.controllerData = input,
         onSaved: (input) => controller.age.value = input,
         controller: ,
         controller: controller.controllerAge,
      ),
      DropdownButtonFormField<bool>(
        value: fieldData.locationId,
        items: items,
        isExpanded: true,
        decoration: const InputDecoration(labelText: 'Status'),
        onSaved: (value) => controller.status.value = value,
       ),
       ),
   ]),
   ]),
Zeile 84: Zeile 134:


void store(controller, String input){
void store(controller, String input){
    if (controller, formKey.currentState?.validate() ?? false) {
  if (controller, formKey.currentState?.validate() ?? false) {
      controller.formKey.currentState?.save();
    controller.formKey.currentState?.save();
    }
  }
}
}
</pre>
</pre>
Zeile 113: Zeile 163:
);
);


</pre>
== DropDownField ==
<pre>
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; },
);
</pre>
</pre>



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,
    ),
  );
}