flutter在列表页面中通过监听列表滑动偏移量控制页面中某个控件的透明度
问题:使用scrollController.addListener直接在列表页面中改变透明度;会因为setState((){})刷新的是整个页面导致滑动时页面卡顿。
解决:将透明度控件放入StatelessWidget中通过StatefulBuilder实现滚动刷新透明值时,UI只刷新该控件。
1.被控制透明度的控件
import 'package:flutter/material.dart';
/*
* 体验购appbar(带需要展位格口数量显示的单元 停在appbar底部,视觉欺骗实现悬停)
* */
class ConfigOpacityWidget extends StatelessWidget{final Widget childOne;final Widget? childTwo;ConfigOpacityWidget({required this.childOne,this.childTwo});late Function updateOpacity;double _opacity = 0.0;bool _sliverOutOfView = false; Widget build(BuildContext context) {// TODO: implement buildreturn StatefulBuilder(builder: (context, setStateBuilder) {updateOpacity = (double opacity,bool sliverOutOfView) {setStateBuilder((){_opacity = opacity;_sliverOutOfView = sliverOutOfView;});};return Column(children: [AnimatedOpacity(opacity: _opacity,duration: Duration(milliseconds: 100),child: childOne,),if(childTwo != null)AnimatedOpacity(opacity: _sliverOutOfView ? 1.0 : 0.0,duration: Duration(milliseconds: 100),child: childTwo,),],);});}
}
2.在有ScrollController控制的页面中引用
late ScrollController _scrollController;
double _opacity = 0.0;
late ConfigOpacityWidget _appbarWidget;void initState() {// TODO: implement initStatesuper.initState();_scrollController = ScrollController();_scrollController.addListener(_scrollListener);_httpData();}_scrollListener(){double _offset = _scrollController.offset;_opacity = (0 + _offset / Constant.APPBAR_SCROLL_OFFSET).clamp(0.0, 1.0); // 0.0 到 1.0 之间bool _isSliverOutOfView = false;if(_offset > _sliverWidgetHeight * 0.8){_isSliverOutOfView = true;if(_currentTabIndex == 2){if(_videoController.value.isPlaying == true){_videoController.pause();}}} else {_isSliverOutOfView = false;if(_currentTabIndex == 2){_videoController.play();}}_appbarWidget.updateOpacity(_opacity,_isSliverOutOfView);}
void dispose() {// TODO: implement dispose_scrollController.dispose();super.dispose();}_setAppbarView(){_appbarWidget = ConfigOpacityWidget(childOne: _appbarView(),childTwo: _cellTitleWidget(),);}_httpData(){
//网络请求成功后
if(mounted){
_setAppbarView();
}
}