在Flutter中自定义组件其实就是一个类,都需要继承StatelessWidget
或者StatefulWidget
.
StatelessWidget
是无状态组件,状态不可改变,我们可以看做为初识状态后一直保持原样,无法通过改变数据再次重新渲染组件.
StatefulWidget
是有状态组件,持有的状态可能在widget
生命周期发生改变,也可以理解为,如果我们在页面上需要数据反复渲染的话,就需要用到这个有状态组件.
StatefulWidget
首先我们先用一个demo
来理解一下StatefulWidget
有状态组件:
- 创建一个
LayoutDemo
类继承StatefulWidget
有状态组件,StatefulWidget
是一个抽象类 -
StatefulWidget
抽象类里面有一个抽象方法createState()
,我们必须要实现这个抽象方法 - 在抽象方法中调用我们自己定义的
_LayoutDemoState
类 -
_LayoutDemoState
类需要继承State
- 实现
_LayoutDemoState
的build
方法,返回一个widget
,这个widget
才是我们需要实现的组件内容
下面我们通过每次点击按钮进行计数的页面功能来理解StatefulWidget
import "package:flutter/material.dart";
void main() => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Container(
child: MaterialApp(
title: 'belineApp',
home: Scaffold(
appBar: AppBar(
title: Text('Wrap'),
),
body: LayoutDemo()
)
)
);
}
}
//- 自定义有状态组件
class LayoutDemo extends StatefulWidget {
LayoutDemo({Key key}) : super(key: key);
_LayoutDemoState createState() => _LayoutDemoState();
}
class _LayoutDemoState extends State {
int countNum = 0;
@override
Widget build(BuildContext context) {
return Column(
children: [
Chip(
label: Text('${this.countNum}'),
),
SizedBox(height:20),
RaisedButton(
child: Text('按钮'),
onPressed: () {
//- setState 方法只有在有状态组件中才有
setState(() {
this.countNum++;
});
},
)
],
);
}
}
页面功能效果
根据上面的demo,我们再实现一个功能需求:
- 新增数据功能,给空的
listview
组件添加listTile
并且每条数据显示对应的编号 -
实现数据清空功能,并清空编号
效果:
代码如下:
import "package:flutter/material.dart";
void main() => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Container(
child: MaterialApp(
title: 'belineApp',
home: Scaffold(
appBar: AppBar(
title: Text('StatefulWidget'),
),
body: HomePage()
)
)
);
}
}
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State {
List list =new List(); //- 定义一个数组变量来装新增的内容
int countNum = 0; //- 用于记住数量
@override
Widget build(BuildContext context) {
return ListView(
children: [
Column(
children: this.list.map((value){ //- 通过遍历数组返回ListTile组件
return ListTile(
title: Text(value)
);
}).toList(), //- 由于map方法返回的不是一个数组,所以我们需要调用toList()方法转换成数组
),
SizedBox(height:20),
RaisedButton(
child: Text('新增数据'),
onPressed: () {
setState(() {
this.countNum++;
this.list.add('新增数据第${this.countNum}条'); //- 调用数组的add方法,添加一个str内容在数组中
});
},
),
RaisedButton(
child: Text('清空'),
onPressed: (){ //- 清空功能按钮
setState(() {
this.countNum = 0;
this.list = [];
});
},
)
],
);
}
}
下面部分为个人练习:
- 引入dio组件(网络请求)
- 通过请求的数据进行页面渲染
-
图文列表中,如果没有图片,用一张暂无图片代替
页面效果:
代码:
import "package:flutter/material.dart";
import "package:dio/dio.dart";
void main() => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Container(
child: MaterialApp(
title: 'belineApp',
home: Scaffold(
appBar: AppBar(
title: Text('StatefulWidget'),
),
body: HomePage()
)
)
);
}
}
getHttp() async {
try {
Response response = await Dio().get("http://rap2.taobao.org:38080/app/mock/228170/datalist");
return response;
// print(response);
} catch (e) {
print(e);
}
}
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State {
List list =new List(); //- 定义一个数组变量来装新增的内容
int countNum = 0; //- 用于记住数量
@override
Widget build(BuildContext context) {
return ListView(
children: [
Column(
children: this.list.map((value){ //- 通过遍历数组返回ListTile组件
return Container(
decoration: BoxDecoration(
border: Border.all(color: Color(0xFFFF0000), width: 0.5)
),
child: ListTile(
leading: Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new NetworkImage('https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3956878071,2257649761&fm=26&gp=0.jpg'), // 设置一个暂无图片的背景
fit: BoxFit.fill // 填满
),
),
child: Image.network(value['coverOneToOne'], width:100.0,height:100.0, fit:BoxFit.cover),
),
title: Text(value['title']),
subtitle: Text(value['summary']),
)
);
}).toList(), //- 由于map方法返回的不是一个数组,所以我们需要调用toList()方法转换成数组
),
SizedBox(height:20),
RaisedButton(
child: Text('新增数据'),
onPressed: () {
getHttp().then((res){
print(res.data['datas']);
setState(() {
this.list = res.data['datas'];
});
});
},
),
RaisedButton(
child: Text('清空'),
onPressed: (){ //- 清空功能按钮
setState(() {
// this.countNum = 0;
this.list = [];
});
},
)
],
);
}
}