Scroll 颤振:改变小部件不透明度和卷轴颜色的最佳方式

Scroll 颤振:改变小部件不透明度和卷轴颜色的最佳方式,scroll,colors,flutter,opacity,flutter-appbar,Scroll,Colors,Flutter,Opacity,Flutter Appbar,我的目标是在用户向下滚动时更改appbar的颜色和不透明度 我的逻辑是: 滚动偏移量=0:appbar为红色,不透明度=1 0\u ProductDetailsState(); } 类_ProductDetailsState扩展状态 使用TickerProviderStateMixin{ AnimationController _ColorAnimationController; AnimationController _TextAnimationController; 动画(彩色之间),;

我的目标是在用户向下滚动时更改appbar的颜色和不透明度

我的逻辑是:

  • 滚动偏移量=0:appbar为红色,不透明度=1
  • 0<滚动偏移<40:appbar为蓝色,不透明度=0.4
  • 40 runApp(MyApp()); 类MyApp扩展了无状态小部件{ @凌驾 小部件构建(构建上下文){ 返回材料PP( 标题:“颤振演示”, 主题:主题数据( 主样本:颜色。蓝色, ), 主页:MyHomePage(标题:“颤振演示主页”), ); } } 类MyHomePage扩展StatefulWidget{ MyHomePage({Key,this.title}):超级(Key:Key); 最后的字符串标题; @凌驾 _MyHomePageState createState()=>\u MyHomePageState(); } 类_MyHomePageState扩展状态{ var_gradientColor1=颜色。红色[400]; var_gradientColor2=颜色。红色[800]; ScrollController\u scrollViewController; void changeColor(){ 如果((_scrollViewController.offset==0)和(_gradientColor1!=Colors.red[400])){ 设置状态(){ _gradientColor1=颜色。红色[400]; _gradientColor2=颜色。红色[800]; });
    }否则如果(_scrollViewController.offset我认为最好的方法是使用
    AnimatedBuilder
    ,您将看到主体中的第一个容器不会更改其颜色,因为小部件状态没有更改 结果是:

    代码:

    import 'dart:math';
    import 'package:flutter/material.dart';
    
    class ProductDetails extends StatefulWidget {
      @override
      _ProductDetailsState createState() => _ProductDetailsState();
    }
    
    class _ProductDetailsState extends State<ProductDetails>
        with TickerProviderStateMixin {
      AnimationController _ColorAnimationController;
      AnimationController _TextAnimationController;
      Animation _colorTween, _iconColorTween;
      Animation<Offset> _transTween;
    
      @override
      void initState() {
        _ColorAnimationController =
            AnimationController(vsync: this, duration: Duration(seconds: 0));
        _colorTween = ColorTween(begin: Colors.transparent, end: Color(0xFFee4c4f))
            .animate(_ColorAnimationController);
        _iconColorTween = ColorTween(begin: Colors.grey, end: Colors.white)
            .animate(_ColorAnimationController);
    
    
        _TextAnimationController =
            AnimationController(vsync: this, duration: Duration(seconds: 0));
    
        _transTween = Tween(begin: Offset(-10, 40), end: Offset(-10, 0))
            .animate(_TextAnimationController);
    
        super.initState();
      }
    
      bool _scrollListener(ScrollNotification scrollInfo) {
        if (scrollInfo.metrics.axis == Axis.vertical) {
          _ColorAnimationController.animateTo(scrollInfo.metrics.pixels / 350);
    
          _TextAnimationController.animateTo(
              (scrollInfo.metrics.pixels - 350) / 50);
          return true;
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Color(0xFFEEEEEE),
          body: NotificationListener<ScrollNotification>(
            onNotification: _scrollListener,
            child: Container(
              height: double.infinity,
              child: Stack(
                children: <Widget>[
                  SingleChildScrollView(
                    child: Column(
                      children: <Widget>[
                        Container(
                          height: 150,
                          color:
                              Color((Random().nextDouble() * 0xFFFFFF).toInt() << 0)
                                  .withOpacity(1),
                          width: 250,
                        ),
                        Container(
                          height: 150,
                          color: Colors.pink,
                          width: 250,
                        ),
                        Container(
                          height: 150,
                          color: Colors.deepOrange,
                          width: 250,
                        ),
                        Container(
                          height: 150,
                          color: Colors.red,
                          width: 250,
                        ),
                        Container(
                          height: 150,
                          color: Colors.white70,
                          width: 250,
                        ),
                      ],
                    ),
                  ),
                  Container(
                    height: 80,
                    child: AnimatedBuilder(
                      animation: _ColorAnimationController,
                      builder: (context, child) => AppBar(
                        backgroundColor: _colorTween.value,
                        elevation: 0,
                        titleSpacing: 0.0,
                        title: Transform.translate(
                          offset: _transTween.value,
                          child: Text(
                            "اسم کالا اینجا",
                            style: TextStyle(
                                color: Colors.white,
                                fontWeight: FontWeight.bold,
                                fontSize: 16),
                          ),
                        ),
                        iconTheme: IconThemeData(
                          color: _iconColorTween.value,
                        ),
                        actions: <Widget>[
                          IconButton(
                            icon: Icon(
                              Icons.local_grocery_store,
                            ),
                            onPressed: () {
    //                          Navigator.of(context).push(TutorialOverlay());
                            },
                          ),
                          IconButton(
                            icon: Icon(
                              Icons.more_vert,
                            ),
                            onPressed: () {},
                          ),
                        ],
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }
    
    import'dart:math';
    进口“包装:颤振/材料.省道”;
    类ProductDetails扩展了StatefulWidget{
    @凌驾
    _ProductDetailsState createState()=>\u ProductDetailsState();
    }
    类_ProductDetailsState扩展状态
    使用TickerProviderStateMixin{
    AnimationController _ColorAnimationController;
    AnimationController _TextAnimationController;
    动画(彩色之间),;
    动画(transTween),;
    @凌驾
    void initState(){
    _彩色动画控制器=
    AnimationController(vsync:this,duration:duration(秒:0));
    _colorTween=colorTween(开始:Colors.transparent,结束:Color(0xFFee4c4f))
    .设置动画(_ColorAnimationController);
    _iconColorTween=ColorTween(开始:Colors.grey,结束:Colors.white)
    .设置动画(_ColorAnimationController);
    _文本动画控制器=
    AnimationController(vsync:this,duration:duration(秒:0));
    _transTween=Tween(开始:偏移(-10,40),结束:偏移(-10,0))
    .animate(_TextAnimationController);
    super.initState();
    }
    bool\u scrollListener(ScrollNotification scrollInfo){
    if(scrollInfo.metrics.axis==axis.vertical){
    _ColorAnimationController.animateTo(scrollInfo.metrics.pixels/350);
    _TextAnimationController.animateTo(
    (scrollInfo.metrics.pixels-350)/50);
    返回true;
    }
    }
    @凌驾
    小部件构建(构建上下文){
    返回脚手架(
    背景颜色:颜色(0xffeeee),
    正文:NotificationListener(
    onNotification:\u滚动侦听器,
    子:容器(
    高度:双无限,
    子:堆栈(
    儿童:[
    SingleChildScrollView(
    子:列(
    儿童:[
    容器(
    身高:150,
    颜色:
    颜色((Random().nextDouble()*0xFFFFFF).toInt()应用程序栏(
    背景颜色:_colorTween.value,
    海拔:0,
    标题间距:0.0,
    标题:Transform.translate(
    偏移量:_transTween.value,
    子:文本(
    "اسم کالا اینجا",
    样式:TextStyle(
    颜色:颜色,白色,
    fontWeight:fontWeight.bold,
    尺寸:16),,
    ),
    ),
    iconTheme:IconThemeData(
    颜色:_iconColorTween.value,
    ),
    行动:[
    图标按钮(
    图标:图标(
    Icons.local_杂货店,
    ),
    已按下:(){
    //Navigator.of(context.push(TutorialOverlay());
    },
    ),
    图标按钮(
    图标:图标(
    图标。更多信息,
    ),
    按下:(){},
    ),
    ],
    ),
    ),
    ),
    ],
    ),
    ),
    ),
    );
    }
    }
    
    用户滚动的每一帧都会调用
    setState
    。可能会添加一个检查,检查颜色是否已经是您想要设置的颜色,然后不要调用
    setState
    。例如,在第一个
    if
    中,检查颜色是否也不是
    颜色。红色[400]
    颜色。红色[800]
    。这样你就不会有那么多调用
    setState
    @tudorprodan的调用了,我已经在每个if中进行了检查,即:_gradientColor1!=Colors.red[400]
    import 'dart:math';
    import 'package:flutter/material.dart';
    
    class ProductDetails extends StatefulWidget {
      @override
      _ProductDetailsState createState() => _ProductDetailsState();
    }
    
    class _ProductDetailsState extends State<ProductDetails>
        with TickerProviderStateMixin {
      AnimationController _ColorAnimationController;
      AnimationController _TextAnimationController;
      Animation _colorTween, _iconColorTween;
      Animation<Offset> _transTween;
    
      @override
      void initState() {
        _ColorAnimationController =
            AnimationController(vsync: this, duration: Duration(seconds: 0));
        _colorTween = ColorTween(begin: Colors.transparent, end: Color(0xFFee4c4f))
            .animate(_ColorAnimationController);
        _iconColorTween = ColorTween(begin: Colors.grey, end: Colors.white)
            .animate(_ColorAnimationController);
    
    
        _TextAnimationController =
            AnimationController(vsync: this, duration: Duration(seconds: 0));
    
        _transTween = Tween(begin: Offset(-10, 40), end: Offset(-10, 0))
            .animate(_TextAnimationController);
    
        super.initState();
      }
    
      bool _scrollListener(ScrollNotification scrollInfo) {
        if (scrollInfo.metrics.axis == Axis.vertical) {
          _ColorAnimationController.animateTo(scrollInfo.metrics.pixels / 350);
    
          _TextAnimationController.animateTo(
              (scrollInfo.metrics.pixels - 350) / 50);
          return true;
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Color(0xFFEEEEEE),
          body: NotificationListener<ScrollNotification>(
            onNotification: _scrollListener,
            child: Container(
              height: double.infinity,
              child: Stack(
                children: <Widget>[
                  SingleChildScrollView(
                    child: Column(
                      children: <Widget>[
                        Container(
                          height: 150,
                          color:
                              Color((Random().nextDouble() * 0xFFFFFF).toInt() << 0)
                                  .withOpacity(1),
                          width: 250,
                        ),
                        Container(
                          height: 150,
                          color: Colors.pink,
                          width: 250,
                        ),
                        Container(
                          height: 150,
                          color: Colors.deepOrange,
                          width: 250,
                        ),
                        Container(
                          height: 150,
                          color: Colors.red,
                          width: 250,
                        ),
                        Container(
                          height: 150,
                          color: Colors.white70,
                          width: 250,
                        ),
                      ],
                    ),
                  ),
                  Container(
                    height: 80,
                    child: AnimatedBuilder(
                      animation: _ColorAnimationController,
                      builder: (context, child) => AppBar(
                        backgroundColor: _colorTween.value,
                        elevation: 0,
                        titleSpacing: 0.0,
                        title: Transform.translate(
                          offset: _transTween.value,
                          child: Text(
                            "اسم کالا اینجا",
                            style: TextStyle(
                                color: Colors.white,
                                fontWeight: FontWeight.bold,
                                fontSize: 16),
                          ),
                        ),
                        iconTheme: IconThemeData(
                          color: _iconColorTween.value,
                        ),
                        actions: <Widget>[
                          IconButton(
                            icon: Icon(
                              Icons.local_grocery_store,
                            ),
                            onPressed: () {
    //                          Navigator.of(context).push(TutorialOverlay());
                            },
                          ),
                          IconButton(
                            icon: Icon(
                              Icons.more_vert,
                            ),
                            onPressed: () {},
                          ),
                        ],
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }