先看效果:
Untitled.gif实现方法
目前网上的方法实现这个效果性能比较差,自己写了下.
总体思路:
- 借助Provider进行状态管理,避免其他widget重复build.
- ScrollController的监听滚动.
Code
- 创建个viewModel用于Provider监听
class MyDetailVM extends ChangeNotifier {
double opacityValue = 0;
final _maxOffset = 100;
MyDetailVM(ScrollController scroller) {
print("MyDetailVM init"+scroller.toString());
// 监听滚动
scroller.addListener(() {
double alpha = scroller.offset / _maxOffset;
print("scrollerListener" + scroller.offset.toString());
if (alpha < 0) {
alpha = 0;
} else if (alpha > 1) {
alpha = 1;
}
if ((alpha < 0 && opacityValue == 0) ||
(alpha > 1 && opacityValue == 1)) {
return;
} else {
opacityValue = alpha;
notifyListeners();
}
});
}
}
- 创建一个Widget
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
ScrollController _controller = ScrollController();
return Scaffold(
//body在AppBar后面
extendBodyBehindAppBar: true,
body: ListView(
padding: EdgeInsets.all(0),
controller: _controller,
children: [
Container(
height: 200,
color: Colors.red,
),
Container(
height: 400,
color: Colors.yellow,
),
Container(
height: 400,
color: Colors.red,
),
]),
//appBar必须是PreferredSize的类型
appBar: PreferredSize(
preferredSize: Size.fromHeight(kToolbarHeight),
child: ChangeNotifierProvider(
create: (ctx) => MyDetailVM(_controller),
child: Consumer<MyDetailVM>(
builder: (context, vm, child) {
if (vm.opacityValue == 0) {
//为0的时候就不显示
return Container();
}
return Opacity(
opacity: vm.opacityValue,
child: child,
);
},
child: AppBar(
backgroundColor: Colors.white,
title: Text(
"I'm AppBar",
style: TextStyle(color: Colors.black),
),
),
),
),
));
}
}
网友评论