fluttercandies / extended_tabs

A powerful official extension library of Tab/TabBar/TabView, which support to scroll ancestor or child Tabs when current is overscroll, and set scroll direction and cache extent.
https://fluttercandies.github.io/extended_tabs/
MIT License
268 stars 49 forks source link

[BUG] indicator 在特定情况下绘制错误 #23

Closed shenjingfs closed 2 years ago

shenjingfs commented 2 years ago

运行环境

Flutter: 2.5.0 extended_tabs: 2.3.0

问题描述

主要的问题是 indicator 并没有按照指定的 indicatorSize 参数生效,还有 mainAxisAlignment 在不为 null 的情况下 indicator 也会有问题,详细看下方的测试部分。

测试

demo code ``` import 'package:flutter/material.dart'; import 'package:extended_tabs/extended_tabs.dart'; class ExtendedTabPage extends StatefulWidget { const ExtendedTabPage({Key? key}) : super(key: key); @override State createState() => _ExtendedTabPageState(); } class _ExtendedTabPageState extends State with SingleTickerProviderStateMixin { late TabController _tabController; @override void initState() { super.initState(); _tabController = TabController(length: 3, vsync: this); } @override void dispose() { _tabController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { // 测试参数 var textDirection = TextDirection.ltr; var isScrollable = false; var labelPadding = EdgeInsets.symmetric(horizontal: 16); var indicatorSize = TabBarIndicatorSize.label; var mainAxisAlignment = null; // 固定参数 final indicator = BoxDecoration( borderRadius: BorderRadius.circular(26), color: Colors.blue, ); final labelColor = Colors.black; final unselectedLabelColor = Colors.black54; final labelStyle = TextStyle(fontSize: 14, fontWeight: FontWeight.bold); final unselectedLabelStyle = TextStyle(fontSize: 14); return Scaffold( appBar: AppBar( title: const Text('Extended Tab Page'), ), body: Directionality( textDirection: textDirection, child: Column( children: [ TabBar( controller: _tabController, isScrollable: isScrollable, labelPadding: labelPadding, indicatorSize: indicatorSize, indicator: indicator, labelColor: labelColor, unselectedLabelColor: unselectedLabelColor, labelStyle: labelStyle, unselectedLabelStyle: unselectedLabelStyle, tabs: const [ Tab(text: 'F Tab 1'), Tab(text: 'F Tab 2'), Tab(text: 'F Tab 3'), ], ), Container(height: 16, color: Colors.black12,), ExtendedTabBar( controller: _tabController, isScrollable: isScrollable, labelPadding: labelPadding, indicatorSize: indicatorSize, indicator: indicator, labelColor: labelColor, unselectedLabelColor: unselectedLabelColor, labelStyle: labelStyle, unselectedLabelStyle: unselectedLabelStyle, mainAxisAlignment: mainAxisAlignment, tabs: const [ Tab(text: 'E Tab 1'), Tab(text: 'E Tab 2'), Tab(text: 'E Tab 3'), ], ), Expanded( child: ExtendedTabBarView( controller: _tabController, children: [ for (var i = 1; i <= 3; i++) buildPage(i, textDirection, isScrollable, labelPadding, indicatorSize, mainAxisAlignment), ], ), ), ], ), ), ); } Widget buildPage( int id, TextDirection textDirection, bool isScrollable, EdgeInsetsGeometry? labelPadding, TabBarIndicatorSize indicatorSize, MainAxisAlignment? mainAxisAlignment, ) { return Container( color: Colors.black12, alignment: Alignment.center, child: Text( 'Page $id\n\n' 'textDirection: $textDirection\n' 'labelPadding: $labelPadding\n' 'isScrollable: $isScrollable\n' 'indicatorSize: $indicatorSize\n' 'mainAxisAlignment: $mainAxisAlignment', ), ); } } ```
测试 上面的 `F Tab` 用的是flutter官方 `TabBar`, 下面的 `E Tab` 用的是 `ExtendedTabBar` 除了参数`mainAxisAlignment` 只有 `ExtendedTabBar` 中有,其他参数一致 1. 用demo里的代码 两边tab效果一致 ![Screenshot_2022-05-26-18-10-59-935_com example flutter_test my_flutter_test](https://user-images.githubusercontent.com/12003831/170479095-e8bf08c2-d329-4d35-9a43-c17ae058170f.jpg) 2. `indicatorSize` 改为 `TabBarIndicatorSize.tab` `E Tab` 中的 `indicator` 并不是 `tab` 的尺寸而是 `label` 的尺寸 ![Screenshot_2022-05-26-18-11-15-575_com example flutter_test my_flutter_test](https://user-images.githubusercontent.com/12003831/170479179-5ebfc7c3-dbcc-464e-af40-8cc8040b2853.jpg) 3. `indicatorSize` 改为 `TabBarIndicatorSize.tab` `mainAxisAlignment` 改为 `MainAxisAlignment.start` `E Tab` 中的 `indicator` 前2个tab尺寸正常,但是最后一个tab的右边界有问题 ![Screenshot_2022-05-26-18-13-14-544_com example flutter_test my_flutter_test](https://user-images.githubusercontent.com/12003831/170479202-3c71d23b-fafe-46b1-b788-d3d552f04cea.jpg) ![Screenshot_2022-05-26-18-13-16-102_com example flutter_test my_flutter_test](https://user-images.githubusercontent.com/12003831/170479213-630193bf-6956-454c-96ff-bf349e5dfba0.jpg) 4. `indicatorSize` 改为 `TabBarIndicatorSize.label` `mainAxisAlignment` 改为 `MainAxisAlignment.start` `E Tab` 中的 `indicator` 并不是 `label` 的尺寸而是 `tab` 的尺寸,最后一个tab也一样有问题 ![Screenshot_2022-05-26-18-14-00-325_com example flutter_test my_flutter_test](https://user-images.githubusercontent.com/12003831/170479252-c787dfa2-d032-440f-94d9-f9be259e814c.jpg) ![Screenshot_2022-05-26-18-14-02-264_com example flutter_test my_flutter_test](https://user-images.githubusercontent.com/12003831/170479264-25e6d7e0-7adc-475b-8973-ce08cf582ab0.jpg) 5. `indicatorSize` 改为 `TabBarIndicatorSize.label` `mainAxisAlignment` 改为 `MainAxisAlignment.end` `E Tab` 中的 `indicator` 并不是 `label` 的尺寸而是 `tab` 的尺寸,但是最后一个tab正常 ![Screenshot_2022-05-26-18-14-22-481_com example flutter_test my_flutter_test](https://user-images.githubusercontent.com/12003831/170479289-bd5fed95-ca57-4013-bc60-3150194f1d53.jpg) 6. `isScrollable` 改为 `true` `indicatorSize` 改为 `TabBarIndicatorSize.tab` 同测试3 ![Screenshot_2022-05-26-18-14-57-644_com example flutter_test my_flutter_test](https://user-images.githubusercontent.com/12003831/170479333-636430df-0620-4f4a-a76e-da8d03a3f04f.jpg) 7. `isScrollable` 改为 `true` `labelPadding` 改为 `EdgeInsets.symmetric(horizontal: 8)` `indicatorSize` 改为 `TabBarIndicatorSize.tab` `mainAxisAlignment` 改为 `MainAxisAlignment.center` 和测试3的问题一样 ![Screenshot_2022-05-26-18-20-12-607_com example flutter_test my_flutter_test](https://user-images.githubusercontent.com/12003831/170479375-2106d9de-5d56-48bc-a8fa-721548a687c3.jpg) 8. `isScrollable` 改为 `true` `labelPadding` 改为 `EdgeInsets.symmetric(horizontal: 32)` `indicatorSize` 改为 `TabBarIndicatorSize.tab` `mainAxisAlignment` 改为 `MainAxisAlignment.center` 同上 ![Screenshot_2022-05-26-18-21-03-748_com example flutter_test my_flutter_test](https://user-images.githubusercontent.com/12003831/170479429-83240cbc-9e4a-426d-8490-b97918602c63.jpg) ![Screenshot_2022-05-26-18-20-59-105_com example flutter_test my_flutter_test](https://user-images.githubusercontent.com/12003831/170479390-34cfffcb-c7a0-4712-8c05-f57831c4f2eb.jpg) 9. `textDirection` 改为 `TextDirection.rtl` `indicatorSize` 改为 `TabBarIndicatorSize.tab` `mainAxisAlignment` 改为 `MainAxisAlignment.end` 同测试3 ![Screenshot_2022-05-26-18-23-05-093_com example flutter_test my_flutter_test](https://user-images.githubusercontent.com/12003831/170479443-81c0b423-f1cc-457b-929b-ac2b1b1f1c9c.jpg) 垂直滚动暂时还没有时间测,不知道有没有问题。

其他

问题应该是出在 _IndicatorPainter 里的 indicatorRect方法,看起来是为了适配 mainAxisAlignment,看 mainAxisAlignment 的注释,应该只会影响 isScrollable = false 时的样式,但是在上述的一些情况下会造成负面效果。

zmtzawqlp commented 2 years ago

已修复