Illustration code:
//This widget is used inside a Scaffold
class TabsPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => new TabsPageState();
}
class TabsPageState extends State<TabsPage> with TickerProviderStateMixin {
List<Tab> _tabs;
List<Widget> _pages;
TabController _controller;
@override
void initState() {
super.initState();
_tabs = [
new Tab(text: 'TabOne'),
new Tab(text: 'TabTwo')
];
_pages = [
//Just normal stateful widgets
new TabOne(),
new TabTwo()
];
_controller = new TabController(length: _tabs.length, vsync: this);
}
@override
Widget build(BuildContext context) {
return new Padding(
padding: EdgeInsets.all(10.0),
child: new Column(
children: <Widget>[
new TabBar(
controller: _controller,
tabs: _tabs
),
new SizedBox.fromSize(
size: const Size.fromHeight(540.0),
child: new TabBarView(
controller: _controller,
children: _pages
),
)
],
),
);
}
}--
You received this message because you are subscribed to the Google Groups "Flutter Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to flutter-dev...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
import 'package:flutter/material.dart';
class Profile {
String name;
String mail;
@override
String toString() {
return 'Profile{name: $name, mail: $mail}';
}
}
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Demo App',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _keyScaffold = new GlobalKey<ScaffoldState>();
GlobalKey<FormState> _keyForm = new GlobalKey<FormState>();
Profile profile = new Profile();
@override
Widget build(BuildContext context) {
return new Scaffold(
key: _keyScaffold,
appBar: new AppBar(title: new Text("Profile")),
floatingActionButton: new FloatingActionButton(
onPressed: () {
// Submit and save the form state
final FormState form = _keyForm.currentState;
if(!form.validate()) {
_keyScaffold.currentState.showSnackBar(new SnackBar(content: new Text("Invalid, check both Tabs")));
return;
}
form.save();
_keyScaffold.currentState.showSnackBar(new SnackBar(content: new Text("${profile}")));
},
child: Icon(Icons.save),
),
body: new SingleChildScrollView(
child: new Container(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
// A bunch of contents
new Container(
padding: EdgeInsets.all(20.0),
child: new Text("A bunch of other contents"),
),
_buildTabsWidget()
],
),
),
)
);
}
Widget _buildTabsWidget() {
return new Form(
key: _keyForm,
child: new ProfileTabsPage(profile)
);
}
}
class ProfileTabsPage extends StatefulWidget {
Profile profile;
ProfileTabsPage(this.profile);
@override
State<StatefulWidget> createState() => new ProfileTabsPageState();
}
class ProfileTabsPageState extends State<ProfileTabsPage> with TickerProviderStateMixin {
List<Tab> _tabs;
List<Widget> _pages;
TabController _controller;
@override
void initState() {
super.initState();
_tabs = [
new Tab(text: 'Personal'),
new Tab(text: 'Contacts')
];
_pages = [
//Just normal stateful widgets
new TabOne(widget.profile),
new TabTwo(widget.profile)
];
_controller = new TabController(length: _tabs.length, vsync: this);
}
@override
Widget build(BuildContext context) {
return new Padding(
padding: EdgeInsets.all(10.0),
child: new Column(
children: <Widget>[
new TabBar(
controller: _controller,
tabs: _tabs,
labelColor: Colors.blue,
indicatorColor: Colors.blue,
),
new SizedBox.fromSize(
size: const Size.fromHeight(540.0),
child: new TabBarView(
controller: _controller,
children: _pages
),
)
],
),
);
}
}
class TabOne extends StatefulWidget {
Profile profile;
TabOne(this.profile);
@override
State<StatefulWidget> createState() => new TabOneState();
}
class TabOneState extends State<TabOne> with AutomaticKeepAliveClientMixin {
@override
Widget build(BuildContext context) {
return new TextFormField(
decoration: new InputDecoration(
labelText: "Name",
),
validator: validateEmptyText,
keyboardType: TextInputType.text,
maxLength: 100,
onSaved: (String newValue) {
widget.profile.name = newValue;
},
initialValue: ""
);
}
@override
bool get wantKeepAlive => true;
String validateEmptyText(String value) {
if (value == null || value.isEmpty) {
return "Can't be empty";
}
return null;
}
}
class TabTwo extends StatefulWidget {
Profile profile;
TabTwo(this.profile);
@override
State<StatefulWidget> createState() => new TabTwoState();
}
class TabTwoState extends State<TabTwo> with AutomaticKeepAliveClientMixin {
@override
Widget build(BuildContext context) {
return new TextFormField(
decoration: new InputDecoration(
labelText: "Mail",
),
validator: validateEmptyText,
keyboardType: TextInputType.text,
maxLength: 100,
onSaved: (String newValue) {
widget.profile.mail = newValue;
},
initialValue: ""
);
}
@override
bool get wantKeepAlive => true;
String validateEmptyText(String value) {
if (value == null || value.isEmpty) {
return "Can't be empty";
}
return null;
}
}