前文已经对 Widget 做了概括(Flutter系列之二:Widget_项羽-韩的博客-CSDN博客),本文将结合示例,做说明。
一、StatefulWidget示例
A widget that has mutable state.
这是一个可变状态的 widget。
1.1 MaterialApp介绍
An application that uses material design.
继承自 StatefulWidget,基本元素如下:
MaterialApp(
home: Scaffold(//Scaffold,提供了标准app元素
appBar:,
bottomNavigationBar:,
?????body:,
),
)
1.2 StatefulWidget示例
第一步:类继承了? StatefulWidget,并重写方法?createState(),该方法需返回一个 State 对象;
第二部:创建 State 类,并在类中,通过? ?setState()? 改变 Widget 。
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(
title: 'My app',
home: YellowBird(),
));
}
class YellowBird extends StatefulWidget{
const YellowBird({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _YellowBirdState();
}
}
class _YellowBirdState extends State<YellowBird>{
int _counter = 1000;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('鸟的数量:'+'$_counter'),
IconButton(onPressed: _incrementCounter, icon: Icon(Icons.add)),
],
),
)
);
}
}
1.3? bottomNavigationBar 结合示例
?首先:BottomNavigationBar 有以下基础属性,
items:内容;
currentIndex:当前选中项;
onTap:点击事件;
selectedItemColor:选中项颜色;
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(
title: 'My app',
home: HomePage(),
));
}
List<BottomNavigationBarItem> barItemList = [
const BottomNavigationBarItem(label: '首页', icon: Icon(Icons.home)),
const BottomNavigationBarItem(label: '搜索', icon: Icon(Icons.search)),
const BottomNavigationBarItem(label: '资讯', icon: Icon(Icons.info)),
const BottomNavigationBarItem(label: '我的', icon: Icon(Icons.account_circle)),
];
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
TutorialHome createState() => TutorialHome();
}
class TutorialHome extends State<HomePage> {
int _selectedIndex = 0;
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: const IconButton(
icon: Icon(Icons.menu),
tooltip: 'Navigation menu',
onPressed: null,
),
title: const Text('Example title'),
actions: const <Widget>[
IconButton(
icon: Icon(Icons.search),
tooltip: 'Search',
onPressed: null,
),
],
),
bottomNavigationBar: BottomNavigationBar(
items: barItemList,
currentIndex: _selectedIndex,
type: BottomNavigationBarType.fixed,
selectedItemColor: Colors.indigo,
onTap: _onItemTapped,
),
body: Center(
child:
Text('This is a BottomNavigationBar Example !'),
),
);
}
}
其次,自己熟悉 Scaffold 的其他常用元素,比如:appBar,body等。
二、StatelessWidget 示例
A widget that does not require mutable state.
这是一个不需要可变状态的widget,一般构建静态的UI的时候会使用StatelessWidget。
StatelessWidget 用于不需要维护状态 的场景,它通常在build 方法中通过嵌套其它Widget 来构建UI ,在构建过程中会递归的构建其嵌套的Widget 。
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(
title: 'My app', // used by the OS task switcher
home: GreenFrog(),
));
}
class GreenFrog extends StatelessWidget {
const GreenFrog({ Key? key }) : super(key: key);
@override
Widget build(BuildContext context) {
return Material(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,//垂直方向对齐方式
crossAxisAlignment: CrossAxisAlignment.start,//水平方向对齐方式
children: [
Text("以下都是 StatelessWidget :"),
Icon(Icons.android,//设置图标
size: 50,
color: Colors.red),
IconButton(onPressed: null, icon: Icon(Icons.android)),
Divider(height: 20,indent: 30,endIndent: 30,color: Colors.red),
RaisedButton(onPressed: null,child: Text("RaisedButton-已废弃"),color: Colors.red),
FlatButton(onPressed: null, child: Text("FlatButton-已废弃")),
OutlinedButton(onPressed: null, child: Text("OutlinedButton-已废弃"))
],
)
);
}
}
三、InheritedWidget
Flutter的响应式开发与React类似,数据都是自顶向下的。如Flutter SDK中正是通过InheritedWidget来共享应用主题(Theme )和Locale (当前语言环境)信息的。
假设有祖先组点A,中间经过结点B, C,然后到结点D,D需要从A中获取数据f,那按照自顶向下数据流转,f需要依次传递给B及C,最后才到C。这样开发极为不灵活,成本也比较高。所有Flutter需要有跨结点、高效传递数据的方案。
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(
title: 'Flutter Demo',
home: const MyHomePage(title: 'flutter Demo Home Page'),
));
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int counter = 0;
void incrementCounter() {
setState(() {
counter++;
});
}
@override
Widget build(BuildContext context) {
return InheritedCounter(
data: this,
child: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: IncrementBody(),
floatingActionButton: IncrementButton(), // This trailing comma makes auto-formatting nicer for build methods.
),
);
}
}
class IncrementBody extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'${InheritedCounter.of(context).data.counter}',
style: Theme.of(context).textTheme.displayMedium,
),
],
),
);
}
}
class IncrementButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FloatingActionButton(
onPressed: InheritedCounter.of(context).data.incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
);
}
}
class InheritedCounter extends InheritedWidget {
const InheritedCounter({
Key? key,
required this.data,
required Widget child,
}) : assert(child != null),
super(key: key, child: child);
final _MyHomePageState data;
static InheritedCounter of(BuildContext context) {
final InheritedCounter? result = context.dependOnInheritedWidgetOfExactType<InheritedCounter>();
assert(result != null, 'No InheritedCounter found in context');
return result!;
}
@override
bool updateShouldNotify(InheritedCounter old) => true;
}
多写,多思考,多看几遍API源码。
|