flutter实现透明导航栏

滚动并实现透明导航栏

使用 flutter+getx

views

复制代码
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_xm/app/utils/ityingFonts.dart';
import 'package:flutter_xm/app/utils/keepAliveWrapper.dart';

import 'package:get/get.dart';

import '../controllers/home_controller.dart';

class HomeView extends GetView<HomeController> {
  const HomeView({super.key});

  @override
  Widget build(BuildContext context) {
    return KeepAliveWrapper(
      child: Scaffold(
        extendBodyBehindAppBar: true, // 使内容延伸到AppBar后面,实现沉浸式
        body: Stack(
          children: [
            // 主内容列表
            Positioned.fill(
              child: ListView.builder(
                controller: controller.scrollController,
                padding: EdgeInsets.zero, // 移除顶部padding,实现沉浸式
                itemCount: 20,
                itemBuilder: (context, index) {
                  if (index == 0) {
                    return SizedBox(
                      width: double.infinity,
                      height: 280.h, // 调整轮播图高度
                      child: FadeInImage.assetNetwork(
                        placeholder: 'assets/images/placeholder.png', // 占位图路径
                        placeholderFit: BoxFit.cover,
                        image:
                            "https://www.itying.com/images/focus/focus02.png",
                        fit: BoxFit.cover,
                        fadeInDuration: const Duration(milliseconds: 800),
                        fadeOutDuration: const Duration(milliseconds: 500),
                        imageErrorBuilder: (context, error, stackTrace) {
                          return Container(
                            width: double.infinity,
                            height: double.infinity,
                            color: Colors.grey[200],
                            child: const Center(
                              child: Icon(
                                Icons.image_not_supported,
                                color: Colors.grey,
                                size: 48,
                              ),
                            ),
                          );
                        },
                      ),
                    );
                  } else {
                    // 使用更流畅的动画
                    return SmoothFadeInAnimation(
                      delay: Duration(milliseconds: (index - 1) * 50),
                      child: ListTile(
                        title: Text(
                          "第$index个列表",
                          style: TextStyle(fontSize: 16.sp),
                        ),
                      ),
                    );
                  }
                },
              ),
            ),

            // 自定义AppBar - 悬浮效果
            Positioned(
              top: -30.h,
              left: 0,
              right: 0,
              child: Obx(() {
                final isScrolled = controller.flag.value;
                return Container(
                  padding: EdgeInsets.only(
                    top: MediaQuery.of(context).padding.top,
                  ),
                  decoration: BoxDecoration(
                    gradient: isScrolled
                        ? const LinearGradient(
                            begin: Alignment.topCenter,
                            end: Alignment.bottomCenter,
                            colors: [
                              Colors.white,
                              Color.fromARGB(255, 245, 245, 245),
                            ],
                          )
                        : null,
                    boxShadow: isScrolled
                        ? [
                            BoxShadow(
                              color: Colors.black.withOpacity(0.1),
                              blurRadius: 15,
                              offset: const Offset(0, 5),
                            ),
                          ]
                        : [],
                  ),
                  child: AppBar(
                    backgroundColor: Colors.transparent,
                    elevation: 0,
                    toolbarHeight: kToolbarHeight + 20.h, // 增加工具栏高度,避免太贴底
                    // 设置状态栏样式,与图片水蓝色匹配
                    systemOverlayStyle: const SystemUiOverlayStyle(
                      statusBarColor:
                          Color.fromARGB(0, 64, 191, 255), // 水蓝色透明状态栏
                      statusBarBrightness: Brightness.light,
                      statusBarIconBrightness: Brightness.light,
                    ),
                    leading: AnimatedOpacity(
                      opacity: isScrolled ? 0 : 1,
                      duration: const Duration(milliseconds: 600),
                      curve: Curves.fastOutSlowIn,
                      child: Icon(
                        ItyingFonts.xiaomi,
                        color: isScrolled ? Colors.black87 : Colors.white,
                        size: 32.sp, // 增大图标尺寸
                      ),
                    ),
                    leadingWidth: isScrolled ? 10.w : 40.w,
                    title: AnimatedContainer(
                      duration: const Duration(milliseconds: 600),
                      curve: Curves.fastOutSlowIn,
                      width: isScrolled ? 600.w : 375.w,
                      height: 56.h,
                      margin: EdgeInsets.only(bottom: 5.h), // 增加底部margin,避免太贴底
                      decoration: BoxDecoration(
                        color: isScrolled
                            ? Colors.white
                            : Colors.white.withOpacity(0.2),
                        borderRadius: BorderRadius.circular(60.r),
                        boxShadow: isScrolled
                            ? [
                                BoxShadow(
                                  color: Colors.black.withOpacity(0.08),
                                  blurRadius: 15,
                                  offset: const Offset(0, 3),
                                ),
                              ]
                            : [],
                      ),
                      child: Row(
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: [
                          Padding(
                            padding: EdgeInsets.fromLTRB(20.w, 0, 8.w, 0),
                            child: Icon(
                              Icons.search,
                              color: isScrolled ? Colors.black87 : Colors.white,
                              size: 20.sp,
                            ),
                          ),
                          Text(
                            "手机",
                            style: TextStyle(
                              fontSize: 16.sp,
                              color: isScrolled ? Colors.black54 : Colors.white,
                            ),
                          ),
                        ],
                      ),
                    ),
                    centerTitle: true,
                    actions: [
                      // 直接使用颜色过渡,避免AnimatedSwitcher的闪烁
                      IconButton(
                        onPressed: () {},
                        icon: Icon(
                          Icons.qr_code,
                          color: isScrolled ? Colors.black87 : Colors.white,
                          size: 24.sp,
                        ),
                      ),
                      IconButton(
                        onPressed: () {},
                        icon: Icon(
                          Icons.message,
                          color: isScrolled ? Colors.black87 : Colors.white,
                          size: 24.sp,
                        ),
                      ),
                    ],
                  ),
                );
              }),
            ),
          ],
        ),
      ),
    );
  }
}

// 更流畅的渐入动画组件
class SmoothFadeInAnimation extends StatefulWidget {
  final Widget child;
  final Duration delay;

  const SmoothFadeInAnimation({
    Key? key,
    required this.child,
    this.delay = Duration.zero,
  }) : super(key: key);

  @override
  State<SmoothFadeInAnimation> createState() => _SmoothFadeInAnimationState();
}

class _SmoothFadeInAnimationState extends State<SmoothFadeInAnimation>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _opacityAnimation;
  late Animation<double> _translateAnimation;

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

    _controller = AnimationController(
      duration: const Duration(milliseconds: 1000),
      vsync: this,
    );

    // 使用更平滑的曲线
    final curve = Curves.fastOutSlowIn;

    _opacityAnimation = Tween<double>(
      begin: 0.3,
      end: 1.0,
    ).animate(
      CurvedAnimation(
        parent: _controller,
        curve: curve,
      ),
    );

    _translateAnimation = Tween<double>(
      begin: 10.0,
      end: 0.0,
    ).animate(
      CurvedAnimation(
        parent: _controller,
        curve: curve,
      ),
    );

    // 添加延迟启动动画
    Future.delayed(widget.delay, () {
      _controller.forward();
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (context, child) {
        return Opacity(
          opacity: _opacityAnimation.value,
          child: Transform.translate(
            offset: Offset(0, _translateAnimation.value),
            child: child,
          ),
        );
      },
      child: widget.child,
    );
  }
}

controller

复制代码
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class HomeController extends GetxController {
  final ScrollController scrollController = ScrollController();
  RxBool flag = false.obs;

  @override
  void onInit() {
    super.onInit();
    scrollController.addListener(() {
      if (scrollController.position.pixels > 10) {
        if (flag.value == false) {
          flag.value = true;
          update();
        }
      }
      if (scrollController.position.pixels < 10) {
        if (flag.value == true) {
          flag.value = false;
          update();
        }
      }
    });
  }

  @override
  void onClose() {
    super.onClose();
  }
}
相关推荐
雄鸡三声天下白2 小时前
js复制文本到剪贴板,以及navigator.clipboard 会提示 is undefined
前端·javascript·数据库
OpenTiny社区2 小时前
博文精读:Chrome CSS 2025年回顾
前端·css·chrome·开源·opentiny
珑墨2 小时前
【大语言模型】从历史到未来
前端·人工智能·后端·ai·语言模型·自然语言处理·chatgpt
亿元程序员2 小时前
亿元Cocos小游戏实战合集
前端
fengyucaihong_1232 小时前
vue加声音播放
javascript·vue.js·ecmascript
2503_928411562 小时前
12.26 小程序代码片段【添加WeaUI内容】
前端·微信小程序·小程序
华仔啊2 小时前
Vue3 的设计目标是什么?相比 Vue2 做了哪些关键优化?
前端·vue.js
鹏多多2 小时前
前端纯js实现图片模糊和压缩
前端·javascript·vue.js
长安即是故里2 小时前
搭建一个现代化视频聚合播放平台(含视频源)
前端·音视频·开源项目··部署教程