flutter_extended_scroll 3.2.2 copy "flutter_extended_scroll: ^3.2.2" to clipboard
flutter_extended_scroll: ^3.2.2 copied to clipboard

make method ensureVisible support offsetTop

flutter_extended_scroll package for flutter. #

 make method ensureVisible support offsetTop

Getting Started #

Add the package to your pubspec.yaml:

flutter_extended_scroll: ^3.2.2

example #

详细见example

In your dart file, import the library:

import 'package:flutter_extended_scroll/flutter_extended_scroll.dart';
class DetailPage extends StatefulWidget {
  const DetailPage({super.key});

  static const String name = "/detailPage";

  @override
  State<DetailPage> createState() => _DetailPageState();
}

class _DetailPageState extends State<DetailPage> {
  late final ExtendedScrollController _scrollController;
  late final RefreshController _refreshController;

  bool isTabClicked = false;

  //good、comment、detail、betterGoods card keys
  final cardKeys = <GlobalKey>[
    GlobalKey(debugLabel: 'detail_card_0'),
    GlobalKey(debugLabel: 'detail_card_1'),
    GlobalKey(debugLabel: 'detail_card_2'),
    GlobalKey(debugLabel: 'detail_card_3')
  ];

  @override
  void initState() {
    _scrollController = ExtendedScrollController();
    _refreshController = RefreshController();
    super.initState();
  }

  @override
  void dispose() {
    _scrollController.dispose();
    _refreshController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return StoreBuilder<AppState>(
      onInit: (store) async {
        await store.dispatch(InitPageAction());
      },
      onDispose: (store) {
        store.dispatch(ChangeTopTabIndexAction(0));
      },
      builder: (context, store) {
        bool isLoading = store.state.detailPageState.isLoading;

        List<Widget> stackWidgets = [];
        if (isLoading) {
          stackWidgets.add(loadingWidget(context));
        } else {
          stackWidgets.add(NotificationListener<ScrollNotification>(
            onNotification: (ScrollNotification notification) {
              double distance = notification.metrics.pixels;
              store.dispatch(ChangePageScrollYAction(distance));
              
              if (isTabClicked) return false;
              int newIndex = findFirstVisibleItemIndex(cardKeys, context);
              store.dispatch(ChangeTopTabIndexAction(newIndex));
              return false;
            },
            child: Container(
              child: SmartRefresher(
                controller: _refreshController,
                enablePullUp: true,
                enablePullDown: false,
                onLoading: () async {
                  store.dispatch(LoadMoreAction(
                    store.state.detailPageState.pageNum + 1,
                        () => loadMoreSuccess(_refreshController),
                        () => loadMoreFail(_refreshController),
                  ));
                },
                child: ExtendedCustomScrollView(
                  controller: _scrollController,
                  slivers: [
                    goodsInfo(context, cardKeys[0]),
                    appraiseInfo(context, cardKeys[1]),
                    detailCard(context, cardKeys[2]),
                    storeGoodsHeader(context, cardKeys[3]),
                    storeGoods(context)
                  ],
                ),
              ),
            ),
          ));
        }

        stackWidgets.add(
          Positioned(
            top: 0,
            left: 0,
            child: tabHeader(
              context,
              onChange: (index) {
                isTabClicked = true;
                store.dispatch(ChangeTopTabIndexAction(index));
                scroll2PositionByTabIndex(index);
              },
            ),
          ),
        );

        return AnnotatedRegion<SystemUiOverlayStyle>(
          value: SystemUiOverlayStyle.dark,
          child: Column(
            children: [
              Expanded(
                flex: 1,
                child: Scaffold(
                  body: Stack(
                    children: stackWidgets,
                  ),
                  floatingActionButton: BackToTop(_scrollController),
                ),
              ),
              fixedBottom(context)
            ],
          ),
        );
      },
    );
  }
  
  void scroll2PositionByTabIndex(int index) {
    RenderSliverToBoxAdapter? keyRenderObject = cardKeys[index].currentContext?.findAncestorRenderObjectOfType<RenderSliverToBoxAdapter>();
    if (keyRenderObject != null) {
      _scrollController.position
          .ensureVisible(keyRenderObject, offsetTop: 42 + getStatusHeight(context), duration: const Duration(milliseconds: 300), curve: Curves.linear)
          .then((value) => isTabClicked = false);
    }
  }
  
  int findFirstVisibleItemIndex(List<GlobalKey<State<StatefulWidget>>> cardKeys, BuildContext context) {
    int i = 0;
    for (; i < cardKeys.length; i++) {
      RenderSliverToBoxAdapter? keyRenderObject = cardKeys[i].currentContext?.findAncestorRenderObjectOfType<RenderSliverToBoxAdapter>();
      if (keyRenderObject != null) {
        
        final dy = (keyRenderObject.parentData as SliverPhysicalParentData).paintOffset.dy;
        if (dy > 42 + getStatusHeight(context)) {
          break;
        }
      }
    }
    final newIndex = i == 0 ? 0 : i - 1;
    return newIndex;
  }
}

```.
2
likes
140
points
45
downloads

Publisher

unverified uploader

Weekly Downloads

make method ensureVisible support offsetTop

Homepage
Repository (GitHub)

Documentation

API reference

License

MIT (license)

Dependencies

flutter, meta

More

Packages that depend on flutter_extended_scroll