Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

刷新指示器设置为IndicatorPosition.locator时的问题 #582

Closed
H-Bin opened this issue Aug 1, 2022 · 3 comments
Closed

刷新指示器设置为IndicatorPosition.locator时的问题 #582

H-Bin opened this issue Aug 1, 2022 · 3 comments

Comments

@H-Bin
Copy link

H-Bin commented Aug 1, 2022

在使用example的tabbarview时结合我的业务改动了一下,发现了一点问题

这是代码:

import 'dart:async';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:easy_refresh/easy_refresh.dart';
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';

void main(List<String> args) {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: TabBarViewPage(),
    );
  }
}

class TabBarViewPage extends StatefulWidget {
  const TabBarViewPage({Key? key}) : super(key: key);

  @override
  TabBarViewPageState createState() {
    return TabBarViewPageState();
  }
}

class TabBarViewPageState extends State<TabBarViewPage>
    with SingleTickerProviderStateMixin {
  late TabController _tabController;
  int _listCount = 20;
  int _gridCount = 20;

  Color appColor = Colors.red;

  @override
  void initState() {
    super.initState();
    Timer.periodic(const Duration(seconds: 3), (timer) {
      if (mounted) {
        setState(() {
          appColor = Color.fromRGBO(Random().nextInt(255),
              Random().nextInt(255), Random().nextInt(255), 1);
        });
      }
    });
    _tabController = TabController(length: 2, vsync: this);
  }

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

  @override
  Widget build(BuildContext context) {
    final themeData = Theme.of(context);
    return Scaffold(
      body: EasyRefresh.builder(
        header: ClassicHeader(
          clamping: true,
          position: IndicatorPosition.locator,
          backgroundColor: appColor,
          dragText: 'Pull to refresh',
          armedText: 'Release ready',
          readyText: 'Refreshing...',
          processingText: 'Refreshing...',
          processedText: 'Succeeded',
          noMoreText: 'No more',
          failedText: 'Failed',
          messageText: 'Last updated at %T',
        ),
        footer: const ClassicFooter(
          position: IndicatorPosition.locator,
          dragText: 'Pull to load',
          armedText: 'Release ready',
          readyText: 'Loading...',
          processingText: 'Loading...',
          processedText: 'Succeeded',
          noMoreText: 'No more',
          failedText: 'Failed',
          messageText: 'Last updated at %T',
        ),
        onRefresh: () async {
          await Future.delayed(const Duration(seconds: 2), () {
            if (mounted) {
              setState(() {
                if (_tabController.index == 0) {
                  _listCount = 20;
                } else {
                  _gridCount = 20;
                }
              });
            }
          });
        },
        onLoad: () async {
          await Future.delayed(const Duration(seconds: 2), () {
            // if (mounted) {
            //   setState(() {
            //     if (_tabController.index == 0) {
            //       _listCount += 10;
            //     } else {
            //       _gridCount += 10;
            //     }
            //   });
            // }
          });
        },
        childBuilder: (context, physics) {
          return ExtendedNestedScrollView(
            physics: physics,
            onlyOneScrollInBody: true,
            pinnedHeaderSliverHeightBuilder: () {
              return MediaQuery.of(context).padding.top + kToolbarHeight;
            },
            headerSliverBuilder: (context, innerBoxIsScrolled) {
              return <Widget>[
                const HeaderLocator.sliver(clearExtent: false),
                SliverAppBar(
                  pinned: true,
                  backgroundColor: appColor,
                  flexibleSpace: FlexibleSpaceBar(
                    title: Text(
                      'TabBarView',
                      style: TextStyle(
                          color: Theme.of(context).textTheme.titleLarge?.color),
                    ),
                    titlePadding: const EdgeInsets.only(left: 64, bottom: 60),
                    centerTitle: false,
                  ),
                ),
                SliverToBoxAdapter(
                  child: Container(
                    height: 600,
                    color: Colors.white,
                  ),
                ),
              ];
            },
            body: TabBarView(
              controller: _tabController,
              children: <Widget>[
                ExtendedVisibilityDetector(
                  uniqueKey: const Key('Tab0'),
                  child: CustomScrollView(
                    physics: physics,
                    slivers: [
                      SliverList(
                          delegate:
                              SliverChildBuilderDelegate((context, index) {
                        return Card(
                          color: Colors.white,
                          child: Container(
                            width: MediaQuery.of(context).size.width,
                            height: 50,
                            color: Colors.blue,
                          ),
                        );
                      }, childCount: _listCount)),
                      const FooterLocator.sliver(),
                    ],
                  ),
                ),
                ExtendedVisibilityDetector(
                  uniqueKey: const Key('Tab1'),
                  child: CustomScrollView(
                    physics: physics,
                    slivers: [
                      SliverGrid(
                          delegate:
                              SliverChildBuilderDelegate((context, index) {
                            return const SkeletonItem(
                              direction: Axis.horizontal,
                            );
                          }, childCount: _gridCount),
                          gridDelegate:
                              const SliverGridDelegateWithFixedCrossAxisCount(
                            crossAxisCount: 2,
                            childAspectRatio: 6 / 7,
                          )),
                      const FooterLocator.sliver(),
                    ],
                  ),
                ),
              ],
            ),
          );
        },
      ),
    );
  }
}

/// Skeleton list item.
class SkeletonItem extends StatelessWidget {
  /// Scrollable direction.
  final Axis direction;

  const SkeletonItem({
    Key? key,
    this.direction = Axis.vertical,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final themeData = Theme.of(context);
    final backgroundColor = themeData.colorScheme.surfaceVariant;
    final foregroundColor = themeData.colorScheme.surface;
    if (direction == Axis.vertical) {
      return Card(
        elevation: 0,
        color: backgroundColor,
        child: Padding(
          padding: const EdgeInsets.all(16),
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Container(
                margin: const EdgeInsets.only(right: 16),
                height: 80,
                width: 80,
                color: foregroundColor,
              ),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Container(
                      margin: const EdgeInsets.only(top: 8, right: 24),
                      height: 12,
                      width: double.infinity,
                      constraints: const BoxConstraints(
                        maxWidth: 200,
                      ),
                      color: foregroundColor,
                    ),
                    Container(
                      margin: const EdgeInsets.only(top: 16),
                      height: 12,
                      width: 80,
                      color: foregroundColor,
                    ),
                    Container(
                      margin: const EdgeInsets.only(top: 8),
                      height: 12,
                      width: 80,
                      color: foregroundColor,
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      );
    }
    return Card(
      elevation: 0,
      color: Theme.of(context).colorScheme.surfaceVariant,
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Container(
              margin: const EdgeInsets.only(bottom: 16),
              height: 80,
              width: 80,
              color: Theme.of(context).splashColor,
            ),
            Expanded(
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Container(
                    margin: const EdgeInsets.only(left: 8, bottom: 24),
                    width: 12,
                    height: double.infinity,
                    constraints: const BoxConstraints(
                      maxHeight: 200,
                    ),
                    color: Theme.of(context).splashColor,
                  ),
                  Container(
                    margin: const EdgeInsets.only(left: 16),
                    width: 12,
                    height: 80,
                    color: Theme.of(context).splashColor,
                  ),
                  Container(
                    margin: const EdgeInsets.only(left: 8),
                    width: 12,
                    height: 80,
                    color: Theme.of(context).splashColor,
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

1.在使用HeaderLocator.sliver()时,如果ExtendedNestedScrollView的headerSliverBuilder里添加了更多sliver组件,HeaderLocator的滑动范围会变小,甚至到了无法触发的地步。如图已经是滑动到最大程度的样子
image

2.在HeaderLocator.sliver()里,backgroundColor属性只会在滑动时生效,如果滑动时悬停不动或者刷新期间backgroud改变是无法生效的,我在demo中写了个定时器,让Header和SliverAppBar的背景色改变,但是在悬停时或者刷新时,能看到,SliverAppBar的颜色改变了,Header颜色没有,默认的指示器并不会出现这个问题
QQ20220801-163325

3.在我注释掉onload里的listCount改变后,footer succeed后并不会自动收起
image

@xuelongqy
Copy link
Owner

非常感谢。第一点可能是滚动阻力的原因,这个得研究一下;第二点没有及时更新属性,这个在下个版本会改进;第三点没有问题的哈,因为是定位,所以会跟随列表,如果需要消失,使用clamping即可

@H-Bin
Copy link
Author

H-Bin commented Aug 1, 2022

非常感谢。第一点可能是滚动阻力的原因,这个得研究一下;第二点没有及时更新属性,这个在下个版本会改进;第三点没有问题的哈,因为是定位,所以会跟随列表,如果需要消失,使用clamping即可

好的,感谢大佬的插件,现在契合业务比较好的刷新插件就是这个了

@xuelongqy
Copy link
Owner

3.0.4+1已修复

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants