flutter:SingleChildScrollView仿tabbar并可滑动

一,代码:

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'Home.dart';

class HistoryDemo extends StatefulWidget {
  @override
  _HistoryDemoState createState() => _HistoryDemoState();
}

class _HistoryDemoState extends State<HistoryDemo> {
  int currentIndex = 0;
  final PageController _pageController = PageController();
  final ScrollController _topController = ScrollController();
  @override
  Widget build(BuildContext context) {
    //得到父state
    HomeState? _ancestor = context.findAncestorStateOfType<HomeState>();
    //得到父state中的pageController
    PageController? _parentController = _ancestor?.pageController;

    return Container(
        color: Colors.white,
        child: Column(
            children: [
          Container(
              margin: EdgeInsets.only(top: 10),
              height: 80,
              child: SingleChildScrollView(
                controller: _topController,
                scrollDirection: Axis.horizontal,
                child:Row(
                  children: <Widget>[
                    SizedBox(width: 20),
                    tabText("推荐", 0),
                    SizedBox(width: 50),
                    tabText("武汉", 1),
                    SizedBox(width: 50),
                    tabText("导购", 2),
                    SizedBox(width: 50),
                    tabText("成都", 3),
                    SizedBox(width: 50),
                    tabText("电商", 4),
                    SizedBox(width: 20),
                  ],
                )
              ),

          ),
          Expanded(
              child: NotificationListener<ScrollNotification>(
          onNotification: (ScrollNotification notification) {
          if (notification is OverscrollNotification) {
             if (currentIndex == 2) {
               var overscrollNotification = notification as OverscrollNotification;
                print("需要切换到上一层");
               _parentController?.position.moveTo(
                   _parentController.offset + overscrollNotification.overscroll);
             }
          }
          return true;
          },

           child:PageView(
                physics: AlwaysScrollableScrollPhysics(),
                onPageChanged: (int page) {    //滑动时改变当前页面
                  setState(() {
                    currentIndex = page;
                  });
                  var left = page*60;
                  _topController.animateTo(
                    left.toDouble(),
                    duration: Duration(milliseconds: 300),
                    curve: Curves.easeInOut,
                  );
                },
                controller: _pageController,     //指定控制器
                scrollDirection: Axis.horizontal, //垂直滑动  默认水平滑动
                children: const [
                  Center(
                    child: Icon(
                      Icons.home,
                      size: 150,
                      color: Colors.blue,
                    ),
                  ),
                  Center(
                    //child: Text("2"),
                    child: Icon(
                      Icons.timeline,
                      size: 150,
                      color: Colors.blue,
                    ),
                  ),
                  Center(
                    child: Icon(
                      Icons.person,
                      size: 150,
                      color: Colors.blue,
                    ),
                  ),
                  Center(
                    child: Icon(
                      Icons.message,
                      size: 150,
                      color: Colors.blue,
                    ),
                  ),
                  Center(
                    child: Icon(
                      Icons.search,
                      size: 150,
                      color: Colors.blue,
                    ),
                  ),
                ],
              )
          )),
        ]));
  }

  /// 导航栏文本样式定义
  RichText tabText(String text1, int index) {
    return RichText(
        text:TextSpan(
        text: text1,
        style: TextStyle(color: currentIndex == index ? Colors.black : Colors.grey,
            fontSize: currentIndex == index ? 40 : 30),
        recognizer: TapGestureRecognizer()
          ..onTap = () {
            setState(() {
              currentIndex = index; // 修改状态并触发 UI 更新
            });
            //把pageview滑动到指定页
            _pageController.animateToPage(
              index,
              duration: Duration(milliseconds: 300),
              curve: Curves.easeInOut,
            );
          }),
    );
  }
}

二,测试效果:

 

posted @ 2025-04-19 10:40  刘宏缔的架构森林  阅读(25)  评论(0)    收藏  举报