106. Form
This widget creates a container for multiple form fields and allows you to validate everything with just one button.
final _formKey = GlobalKey<FormState>();
class Widget106 extends StatelessWidget {
const Widget106({super.key});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(10),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Enter Something';
}
return null;
},
),
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Enter Something';
}
return null;
},
),
TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Enter Something';
}
return null;
},
),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('All forms were filled correctly'),
),
);
}
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Please input the correct information!'),
),
);
},
child: const Text('Done'),
),
],
),
),
);
}
}
107. FractionalTranslation
The FractionalTranslation widget translates its child's painting. In the example below, even though the second Container is in a Column, because it is wrapped with the FractionalTranslation widget, we can change the position instead of it being stacked vertically. We pass an Offset widget to the translation to define the position we want the child to be in. Keep in mind that the Container still takes up its original space vertically so if we were to put a third widget or Container we’d still see the space there.
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
color: Colors.blueGrey,
height: 100,
width: 100,
),
FractionalTranslation(
translation: const Offset(1, -1),
child: Container(
color: Colors.deepPurple,
height: 100,
width: 100,
),
),
Container(
color: Colors.deepOrange,
height: 100,
width: 100,
),
FractionalTranslation(
translation: const Offset(1, -2),
child: Container(
color: Colors.blue,
height: 100,
width: 100,
),
),
],
);
}
108. FractionallySizedBox
The FractionallySizedBox widget sizes its child to a fraction of the total available space. In the example below, we were to set the heightFactor to 1, the Container will take up the height of the screen. This widget also has an alignment property.
@override
Widget build(BuildContext context) {
return Center(
child: FractionallySizedBox(
widthFactor: 0.5,
heightFactor: 0.5,
child: Container(
color: Colors.blueGrey,
),
),
);
}
109. FutureBuilder
This widget builds itself based on the latest snapshot of interaction with a Future. It has an initialData argument that will be provided until the future has completed.
class _Widget109State extends State<Widget109> {
Future<String> getData() async {
await Future.delayed(
const Duration(seconds: 1),
);
return 'Super!';
}
@override
Widget build(BuildContext context) {
return Center(
child: FutureBuilder(
future: getData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text(
snapshot.error.toString(),
);
} else {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
snapshot.data.toString(),
),
ElevatedButton(
onPressed: () {
setState(() {});
},
child: const Text('Refresh'),
),
],
);
}
},
),
);
}
}
110. GestureDetector
This widget detects gestures made on it’s child widget. You can pass functions based on how the user interacts with the widget, such as onTap, onDoubleTap, onDoubleTapCancel, onLongPressDown, onPanEnd and the others. In the example below, when the button is tapped, the number increases by 1 and when it is tapped twice it, increase by 10.
class _Widget110State extends State<Widget110> {
int _counter = 0;
@override
Widget build(BuildContext context) {
return Center(
child: GestureDetector(
onTap: () {
setState(() {
_counter += 1;
});
},
onDoubleTap: () {
setState(() {
_counter += 10;
});
},
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 150,
width: 150,
alignment: Alignment.center,
color: Colors.blueGrey,
child: Text(
_counter.toString(),
style: const TextStyle(fontSize: 50),
),
),
const Text('Tap to icrease by 1 and double tap to increase by 10'),
],
),
),
);
}
}