import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:huixiang/retrofit/data/brand.dart'; import 'package:huixiang/view_widget/icon_text.dart'; class StoreTitleTab extends StatefulWidget { final ScrollController scrollController; final List brands; final List globaKeys; final bool isScroll; StoreTitleTab( this.brands, this.globaKeys, this.scrollController, { this.isScroll = false, }); @override State createState() { return _StoreTitleTab(); } } class _StoreTitleTab extends State { int selectedIndex = -1; int selectedIndex1 = -1; bool isVisible = false; List _globalKeys = []; @override void initState() { super.initState(); if (widget.brands != null) { widget.brands.forEach((element) { _globalKeys.add(GlobalKey()); }); } if (widget.scrollController != null && widget.globaKeys != null && widget.globaKeys.length > 0) { widget.scrollController?.addListener(() { if (widget.globaKeys[0].currentContext == null) return; RenderBox firstRenderBox = widget.globaKeys[0].currentContext.findRenderObject(); Offset first = firstRenderBox?.localToGlobal(Offset.zero); var top = 96.h; if (first.dy <= top) { if (!isVisible) { isVisible = true; setState(() {}); } } else { var b = isVisible; isVisible = false; if (b) setState(() {}); selectedIndex = -1; } widget.globaKeys.forEach((element) { if (widget.globaKeys.indexOf(element) < (widget.globaKeys.length - 1)) { if (element.currentContext == null) return; RenderBox renderBox = element.currentContext.findRenderObject(); Offset offset = renderBox?.localToGlobal(Offset.zero); int nextIndex = widget.globaKeys.indexOf(element) + 1; RenderBox nextRenderBox = widget.globaKeys[nextIndex].currentContext.findRenderObject(); Offset nextOffset = nextRenderBox?.localToGlobal(Offset.zero); if (offset.dy <= top && nextOffset.dy > top) { selectedIndex = widget.globaKeys.indexOf(element); if (selectedIndex1 != selectedIndex) { setState(() { print("object:$selectedIndex"); if (!isClickScroll) { scrollTab(selectedIndex); } else if (selectedIndex == clickIndex) { isClickScroll = false; clickIndex = -1; } }); selectedIndex1 = selectedIndex; } return; } } else { RenderBox lastRenderBox = element.currentContext.findRenderObject(); Offset lastOffset = lastRenderBox?.localToGlobal(Offset.zero); if (lastOffset.dy <= top) { selectedIndex = widget.globaKeys.indexOf(element); if (selectedIndex1 != selectedIndex) { setState(() { print("object:$selectedIndex"); if (!isClickScroll) { scrollTab(selectedIndex); } else if (selectedIndex == clickIndex) { isClickScroll = false; clickIndex = -1; } }); selectedIndex1 = selectedIndex; } return; } } }); }); } } scrollTab(index) { if (_globalKeys[index].currentContext == null) return; RenderBox renderBox = _globalKeys[index].currentContext.findRenderObject(); Offset nextOffset = renderBox?.localToGlobal(Offset.zero); double widgetWidth = renderBox.size.width; double screenWidth = MediaQuery.of(context).size.width; if (nextOffset.dx < 0 || (nextOffset.dx + widgetWidth) > screenWidth) { scrollController.animateTo( nextOffset.dx/* < 0 ? nextOffset.dx : (nextOffset.dx + widgetWidth)*/, duration: Duration(seconds: 1), curve: Curves.ease, ); } } ScrollController scrollController = ScrollController(); @override Widget build(BuildContext context) { return Visibility( visible: (!widget.isScroll) ? true : isVisible, child: SingleChildScrollView( scrollDirection: Axis.horizontal, controller: scrollController, physics: BouncingScrollPhysics(), child: Container( height: 52.h, constraints: BoxConstraints(minWidth: MediaQuery.of(context).size.width), color: Colors.white, alignment: Alignment.center, child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, crossAxisAlignment: CrossAxisAlignment.center, children: (widget.brands == null || widget.brands.length == 0) ? [] : (widget.brands.map((e) { return item(e, selectedIndex == widget.brands.indexOf(e), widget.brands.indexOf(e)); }).toList()), ), ), ), ); } bool isClickScroll = false; int clickIndex = -1; Widget item(Brand text, isSelected, index) { return GestureDetector( onTap: () { FlexParentData parentData = widget.globaKeys[index].currentContext.findRenderObject().parentData; double offset = parentData.offset.dy - 52.h + 20.h; isClickScroll = true; clickIndex = index; widget.scrollController.animateTo(offset, duration: Duration(seconds: 1), curve: Curves.ease); }, child: Container( key: _globalKeys.length > 0 ? _globalKeys[index] : GlobalKey(), padding: EdgeInsets.symmetric(horizontal: 15.w), child: tabItem(text, isSelected), ), ); } Widget tabItem(Brand text, isSelected) { if (isSelected) { return IconText( text.name, isMax: false, rightImage: text.icon ?? "assets/image/icon_xuanzhong.png", iconSize: 16, iconColor: Colors.red, textStyle: TextStyle( fontWeight: FontWeight.bold, fontSize: 16.sp, color: Color(0xFF353535), ), ); } else { return IconText( text.name, isMax: false, textStyle: TextStyle( fontWeight: FontWeight.bold, fontSize: 16.sp, color: Color(0xFF353535), ), ); } } }