Created
November 23, 2025 09:36
-
-
Save kururu-abdo/9be512a93b6fad61c0e349c5244a5c6e to your computer and use it in GitHub Desktop.
Scroll and update Tab bar
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import 'package:flutter/material.dart'; | |
| void main() => runApp(const MyApp()); | |
| class MyApp extends StatefulWidget { | |
| const MyApp({super.key}); | |
| @override | |
| State<MyApp> createState() => _MyAppState(); | |
| } | |
| class _MyAppState extends State<MyApp> { | |
| GlobalKey sectionOneKey = GlobalKey(); | |
| GlobalKey sectionTwoKey = GlobalKey(); | |
| GlobalKey sectionThreeKey = GlobalKey(); | |
| final ScrollController _scrollController = ScrollController(); | |
| @override | |
| void initState() { | |
| super.initState(); | |
| _scrollController.addListener(_onScroll); | |
| } | |
| int _selectedTab = 0; | |
| void _onScroll() { | |
| RenderBox renderBoxSectionOne = sectionOneKey.currentContext?.findRenderObject() as RenderBox; | |
| RenderBox renderBoxSectionTwo = sectionTwoKey.currentContext?.findRenderObject() as RenderBox; | |
| RenderBox renderBoxSectionThree = sectionThreeKey.currentContext?.findRenderObject() as RenderBox; | |
| Offset positionSectionOne = renderBoxSectionOne.localToGlobal(Offset.zero); | |
| Offset positionSectionTwo = renderBoxSectionTwo.localToGlobal(Offset.zero); | |
| Offset positionSectionThree = renderBoxSectionThree.localToGlobal(Offset.zero); | |
| // Repeat for other sections | |
| // Example: Check if sectionOne is visible at the top | |
| if (positionSectionOne.dy < MediaQuery.of(context).size.height / 2 && positionSectionOne.dy >= 0) { | |
| // Update selected tab to section one | |
| setState(() { | |
| _selectedTab = 0; // Assuming 0 is the index for section one | |
| }); | |
| } | |
| if (positionSectionTwo.dy < MediaQuery.of(context).size.height / 2 && positionSectionTwo.dy >= 0) { | |
| // Update selected tab to section one | |
| setState(() { | |
| _selectedTab = 1; // Assuming 0 is the index for section one | |
| }); | |
| } | |
| if (positionSectionThree.dy < MediaQuery.of(context).size.height / 2 && positionSectionThree.dy >= 0) { | |
| // Update selected tab to section one | |
| setState(() { | |
| _selectedTab = 2; // Assuming 0 is the index for section one | |
| }); | |
| } | |
| // Add similar checks for other sections | |
| } | |
| @override | |
| void dispose() { | |
| _scrollController.removeListener(_onScroll); | |
| _scrollController.dispose(); | |
| super.dispose(); | |
| } | |
| @override | |
| Widget build(BuildContext context) { | |
| return MaterialApp( | |
| title: 'Material App', | |
| home: Scaffold( | |
| appBar: AppBar( | |
| title:Row( | |
| spacing: 8, | |
| children: ['Section one', 'Section 2' , 'Section 3'].map((tab)=> | |
| Column( | |
| crossAxisAlignment: .start, | |
| spacing: 5, | |
| mainAxisSize: .min, | |
| children: [ | |
| IntrinsicWidth( | |
| child: Column( | |
| children: [ | |
| Text(tab), | |
| _selectedTab==['Section one', 'Section 2', 'Section 3'].indexOf(tab)? | |
| Divider( | |
| color: | |
| _selectedTab==['Section one', 'Section 2'].indexOf(tab)? | |
| Colors.amber: Colors.grey[500], | |
| thickness: 5, | |
| ): | |
| Divider( | |
| color: | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment