logo头像
Snippet 博客主题

Flutter app 6.下拉刷新

Flutter app 6.下拉刷新

1.添加 下拉刷新

创建启动页
pages/SnapTabPage.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@override
Widget build(BuildContext context) {
print(" build ");

if (listData == null ) {
return new Center(
child: new CircularProgressIndicator(),
);
} else {

print(" listData " + listData.toString());
var refreshIndicator = new RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: _pullToRefresh, // onRefresh 参数是一个 Future<Null> 的回调
child: new ListView.builder(
// 这句是在list里面的内容不足一屏时,list可能会滑不动,加上就一直都可以滑动
physics: const AlwaysScrollableScrollPhysics(),
itemCount: this.listData.length,
itemBuilder: (_, int index) => _createItem(listData[index]),
),
);
return refreshIndicator;
}
}

完整代码
main.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

class SnapTabPage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new SnapTabPageState();
}
}

class SnapTabPageState extends State<SnapTabPage> {

// 这个key用来在不是手动下拉,而是点击某个button或其它操作时,代码直接触发下拉刷新
final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey = new GlobalKey<RefreshIndicatorState>();

var listData;
ScrollController _controller = new ScrollController();

@override
void initState() {
super.initState();
print(" initState ");

getList(false);
}


SnapTabPageState() {
print(" SnapTabPageState ");
}


@override
Widget build(BuildContext context) {
print(" build ");

if (listData == null ) {
return new Center(
child: new CircularProgressIndicator(),
);
} else {

print(" listData " + listData.toString());
var refreshIndicator = new RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: _pullToRefresh, // onRefresh 参数是一个 Future<Null> 的回调
child: new ListView.builder(
// 这句是在list里面的内容不足一屏时,list可能会滑不动,加上就一直都可以滑动
physics: const AlwaysScrollableScrollPhysics(),
itemCount: this.listData.length,
itemBuilder: (_, int index) => _createItem(listData[index]),
),
);

return refreshIndicator;
}

}


getList(bool isLoadMore) async {

var session = await new DataHelper().getSession();

String url = Api.queryAll + Api.session + session.toString();
print("queryAll : $url");

NetUtils.get(url).then((data) {
if (data != null) {
Map<String, dynamic> map = json.decode(data);

print("map : $map");

if (map['messageCode'] == 200 || 'ok' == map['message']) {
var data = map['data'];
setState(() {
if (null != data ){
List list1 = new List();
list1.addAll(data);
listData = list1 ;
}
});
}
}
});

}



Future<Null> _pullToRefresh() async {
getList(false);
return null;
}



Widget renderRow(i) {
var layout = new Column(
children: <Widget>[
new Text('Deliver features faster'),
new Text('Craft beautiful UIs'),
new Expanded(
child: new FittedBox(
fit: BoxFit.contain, // otherwise the logo will be tiny
child: const FlutterLogo(),
),
),
],
);


return new InkWell(
child: layout,
onTap: () {
Navigator.of(context).push(new MaterialPageRoute(
builder: (ctx) => null
));
},
);
}

_createItem(listData) {

print(" _createItem "+ listData.toString() );
return new Column(
children: <Widget>[
new Container(
height: 24.0,
margin: const EdgeInsets.all(10.0),
alignment: Alignment.center,
child: new Text(listData["name"]),
),
new Container(
height: 200.0,
),
new Divider(
height: 0.5,
)
],
);
}

}

UI 布局

1.开启 视觉调试开关

1
布局控件也是可以模拟显示的,通常用于调试布局样式时用到的网格线、标尺、动画帧等。启用方式:

在main.dart中,引入包:

1
import 'package:flutter/rendering.dart' show debugPaintSizeEnabled;

打开视觉调试开关

1
2
3
4
5
6
7
8
9
10
11
12
13
void main() {
debugPaintSizeEnabled = true; //打开视觉调试开关
runApp(
new MaterialApp(
title: 'Snap',
home: new SplashPage(), // 闪屏页,
routes: <String, WidgetBuilder>{ // 路由
'/LoginPage': (BuildContext context) => new LoginPage(),
'/HomePage': (BuildContext context) => new MainPage(),
},
),
);
}

开启后效果

调整UI

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
_createItem(listData) {

print(" _createItem "+ listData.toString() );

print(" thumbUrl "+ listData["thumbUrl"] );
var imgUrl = listData['thumbUrl'];


return new Column(
children: <Widget>[
// title
new Container(
height: 24.0,
margin: const EdgeInsets.all(10.0),
alignment: Alignment.center,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Text(listData["name"]),
new Row(
children: <Widget>[
new Container(
decoration: new BoxDecoration(
// color: const Color(0xfffce5cd),
border: new Border.all( color: Colors.grey, width: 1.0),
borderRadius: new BorderRadius.circular(50.0),
),
child: new Row(
children: <Widget>[
new Padding(
padding: new EdgeInsets.only(top:2.0, bottom: 2.0, left: 2.0),
child: new Image.asset("images/brightness_selected.png",
width: 30.0 ,
height: 30.0,
fit: BoxFit.contain,
),
),

new Padding(
padding: new EdgeInsets.only(right: 5.0),
child: new Text("OFF"),
),
],
),
),

new Image.asset("images/btn_settings_enable.png", width: 60.0),

],

),
],
),
),
new Container(
child: new AspectRatio(
aspectRatio:16/9, //横纵比 长宽比 3:2
child: new Image.network(imgUrl),//项目资源文件
),
),
new Divider(
height: 0.5,
)
],
);
}

  1. 顶部 左右对齐
    使用

    1
    mainAxisAlignment: MainAxisAlignment.spaceBetween,
  2. 圆角

    1
    2
    3
    4
    5
    6
    7
    new Container(
    decoration: new BoxDecoration(
    // color: const Color(0xfffce5cd),
    border: new Border.all( color: Colors.grey, width: 1.0),
    borderRadius: new BorderRadius.circular(50.0),
    ),
    }
  3. padding
    只好这么写了

    1
    2
    3
    4
    5
    6
    7
    8
    new Padding(
    padding: new EdgeInsets.only(top:2.0, bottom: 2.0, left: 2.0),
    child: new Image.asset("images/brightness_selected.png",
    width: 30.0 ,
    height: 30.0,
    fit: BoxFit.contain,
    ),
    ),
  4. 宽高比

    1
    2
    3
    4
    new AspectRatio(
    aspectRatio:3/2, //横纵比 长宽比 3:2
    child: new Image(image: new AssetImage('images/img1.jpg')),//项目资源文件
    ),

虽然 对 flutter 的UI 有各种怨言

但是 还是强忍着 学吧

支付宝打赏 微信打赏

打赏