flutter 监听list滑动 ,渐变appbar的颜色 ,滑动很卡顿 ,可以用这种方式 GlobalKey
页面是一个列表和一个appbar(省略其他代码)
通过GlobalKey 更新appbar的颜色
GlobalKey<AppBarWeightState> barKey;
@override
void initState() {
super.initState();
barKey = GlobalKey();
_retrieveData();
}
这个是 appbar weight
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class AppBarWeight extends StatefulWidget {
AppBarWeight(Key barKey):super(key:barKey);
@override
State<StatefulWidget> createState() {
return new AppBarWeightState();
}
}
class AppBarWeightState extends State<AppBarWeight> {
int _opacity = 0;
@override
Widget build(BuildContext context) {
return AppBar(
elevation: 0,
backgroundColor:
Theme.of(context).primaryColor.withAlpha(_opacity),
title: Text("content",
style: TextStyle(fontSize: 16, color: Colors.grey)),
);
}
void onChange(int alpha) {
setState(() {
_opacity = alpha;
});
}
}
return Column(
children: <Widget>[
AppBarWeight(barKey),//需要更新的 weight
Expanded(
child: NotificationListener<ScrollNotification>(
///此方法需要一个返回值,表示是否拦截住notification,如果是true,那么notifcation到此为止;
///如果是false,那么notification会继续向更外层widget传递。参数ScrollNotification包含了监听到的信息。
onNotification: (ScrollNotification notification) {
ScrollMetrics metrics = notification.metrics;
int extentBefore = metrics.extentBefore.toInt();
if (extentBefore <= _presetOffset) {
_opacity = extentBefore >= _presetOffset
? 255
: extentBefore * 255 ~/ _presetOffset;
barKey.currentState.onChange(_opacity);
}
return true;
},
child: ListView.separated(
itemCount: _words.length,
itemBuilder: (BuildContext context, int index) {
//如果到了表尾
if (_words[index] == loadingTag) {
//不足100条,继续获取数据
if (_words.length - 1 < 100) {
//获取数据
_retrieveData();
//加载时显示loading
return Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.center,
child: SizedBox(
width: 24.0,
height: 24.0,
child: CircularProgressIndicator(strokeWidth: 2.0)),
);
} else {
//已经加载了100条数据,不再获取数据。
return Container(
alignment: Alignment.center,
padding: EdgeInsets.all(16.0),
child: Text(
"没有更多了",
style: TextStyle(color: Colors.grey),
));
}
}
//显示单词列表项
return ListTile(
title: Text(_words[index]),
subtitle: Text(_words[index] + "123"),
);
},
separatorBuilder: (BuildContext context, int index) {
return index % 2 == 0 ? divider1 : divider2;
},
),
))
],
);
AppBarWeight(barKey),//需要更新的 weight
就是appbar 的weight,
onNotification: (ScrollNotification notification) {
ScrollMetrics metrics = notification.metrics;
int extentBefore = metrics.extentBefore.toInt();
if (extentBefore <= _presetOffset) {
_opacity = extentBefore >= _presetOffset
? 255
: extentBefore * 255 ~/ _presetOffset;
barKey.currentState.onChange(_opacity);
}
return true;
},
在onNotification中通过onChange方法改变appbar颜色

源码: