scrollable_positioned_list_extended 0.3.4 copy "scrollable_positioned_list_extended: ^0.3.4" to clipboard
scrollable_positioned_list_extended: ^0.3.4 copied to clipboard

An Extension of scrollable_positioned_list with helper methods like scrollToMax,scrollToMin,jumpToMax and jumToMin it also supports listening to scroll notifications of the primary ScrollController

example/lib/main.dart

// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:math';
import 'package:flutter/material.dart';
import 'package:scrollable_positioned_list_extended/scrollable_positioned_list_extended.dart';

const numberOfItems = 5001;
const minItemHeight = 20.0;
const maxItemHeight = 150.0;
const scrollDuration = Duration(seconds: 2);

const randomMax = 32;

void main() {
  runApp(ScrollablePositionedListExample());
}

// The root widget for the example app.
class ScrollablePositionedListExample extends StatelessWidget {
  const ScrollablePositionedListExample({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ScrollablePositionedList Example',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const ScrollablePositionedListPage(),
    );
  }
}

/// Example widget that uses [ScrollablePositionedList].
///
/// Shows a [ScrollablePositionedList] along with the following controls:
///   - Buttons to jump or scroll to certain items in the list.
///   - Slider to control the alignment of the items being scrolled or jumped
///   to.
///   - A checkbox to reverse the list.
///
/// If the device this example is being used on is in portrait mode, the list
/// will be vertically scrollable, and if the device is in landscape mode, the
/// list will be horizontally scrollable.
class ScrollablePositionedListPage extends StatefulWidget {
  const ScrollablePositionedListPage({Key? key}) : super(key: key);

  @override
  _ScrollablePositionedListPageState createState() =>
      _ScrollablePositionedListPageState();
}

class _ScrollablePositionedListPageState
    extends State<ScrollablePositionedListPage> {
  /// Controller to scroll or jump to a particular item.
  final ItemScrollController itemScrollController = ItemScrollController();

  /// Listener that reports the position of items when the list is scrolled.
  final ItemPositionsListener itemPositionsListener =
      ItemPositionsListener.create();
  late List<double> itemHeights;
  late List<Color> itemColors;
  bool reversed = false;

  /// The alignment to be used next time the user scrolls or jumps to an item.
  double alignment = 0;

  @override
  void initState() {
    super.initState();
    final heightGenerator = Random(328902348);
    final colorGenerator = Random(42490823);
    itemHeights = List<double>.generate(
        numberOfItems,
        (int _) =>
            heightGenerator.nextDouble() * (maxItemHeight - minItemHeight) +
            minItemHeight);
    itemColors = List<Color>.generate(numberOfItems,
        (int _) => Color(colorGenerator.nextInt(randomMax)).withOpacity(1));
    _autoGetPosition();
  }

  void _autoGetPosition() {
    Future.delayed(const Duration(milliseconds: 500), () {
      itemScrollController.scrollListener(
        (notification) {
          debugPrint(notification.position.maxScrollExtent.toString());
          /// do with notification
        },
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      child: OrientationBuilder(
        builder: (context, orientation) => Column(
          children: <Widget>[
            Expanded(
              child: list(orientation),
            ),
            positionsView,
            Row(
              children: <Widget>[
                Column(
                  children: <Widget>[
                    scrollControlButtons,
                    const SizedBox(height: 10),
                    jumpControlButtons,
                    alignmentControl,
                  ],
                ),
                Column(
                  children: [
                    ElevatedButton(
                        onPressed: () {
                          itemScrollController.scrollToMax(
                              duration: const Duration(milliseconds: 800));
                        },
                        child: Text("Scroll To Max")),
                    SizedBox(
                      height: 10,
                    ),
                    ElevatedButton(
                        onPressed: () {
                          itemScrollController.scrollToMin(
                              duration: const Duration(milliseconds: 800));
                        },
                        child: Text("Scroll To Min")),
                  ],
                ),
                SizedBox(
                  width: 10,
                ),
                Column(
                  children: [
                    ElevatedButton(
                        onPressed: () {
                          itemScrollController.jumpToMax();
                        },
                        child: Text("Jump To Max")),
                    SizedBox(
                      height: 10,
                    ),
                    ElevatedButton(
                        onPressed: () {
                          itemScrollController.jumpToMin();
                        },
                        child: Text("Jump To Min")),
                  ],
                ),
              ],
            )
          ],
        ),
      ),
    );
  }

  Widget get alignmentControl => Row(
        mainAxisSize: MainAxisSize.max,
        children: <Widget>[
          const Text('Alignment: '),
          SizedBox(
            width: 200,
            child: SliderTheme(
              data: SliderThemeData(
                showValueIndicator: ShowValueIndicator.always,
              ),
              child: Slider(
                value: alignment,
                label: alignment.toStringAsFixed(2),
                onChanged: (double value) => setState(() => alignment = value),
              ),
            ),
          ),
        ],
      );

  Widget list(Orientation orientation) => ScrollablePositionedList.builder(
      itemCount: numberOfItems,
      itemBuilder: (context, index) => item(index, orientation),
      itemScrollController: itemScrollController,
      addAutomaticKeepAlives: false,
      minCacheExtent: 0,
      itemPositionsListener: itemPositionsListener,
      reverse: reversed,
      scrollDirection: Axis.vertical);

  Widget get positionsView => ValueListenableBuilder<Iterable<ItemPosition>>(
        valueListenable: itemPositionsListener.itemPositions,
        builder: (context, positions, child) {
          int? min;
          int? max;
          if (positions.isNotEmpty) {
            // Determine the first visible item by finding the item with the
            // smallest trailing edge that is greater than 0.  i.e. the first
            // item whose trailing edge in visible in the viewport.
            min = positions
                .where((ItemPosition position) => position.itemTrailingEdge > 0)
                .reduce((ItemPosition min, ItemPosition position) =>
                    position.itemTrailingEdge < min.itemTrailingEdge
                        ? position
                        : min)
                .index;
            // Determine the last visible item by finding the item with the
            // greatest leading edge that is less than 1.  i.e. the last
            // item whose leading edge in visible in the viewport.
            max = positions
                .where((ItemPosition position) => position.itemLeadingEdge < 1)
                .reduce((ItemPosition max, ItemPosition position) =>
                    position.itemLeadingEdge > max.itemLeadingEdge
                        ? position
                        : max)
                .index;
          }
          return Row(
            children: <Widget>[
              Expanded(child: Text('First Item: ${min ?? ''}')),
              Expanded(child: Text('Last Item: ${max ?? ''}')),
              const Text('Reversed: '),
              Checkbox(
                  value: reversed,
                  onChanged: (bool? value) => setState(() {
                        reversed = value!;
                      }))
            ],
          );
        },
      );

  Widget get scrollControlButtons => Row(
        children: <Widget>[
          const Text('scroll to'),
          scrollButton(0),
          scrollButton(5),
          scrollButton(10),
          scrollButton(100),
          scrollButton(99),
          scrollButton(5000),
        ],
      );

  Widget get jumpControlButtons => Row(
        children: <Widget>[
          const Text('jump to'),
          jumpButton(0),
          jumpButton(5),
          jumpButton(10),
          jumpButton(100),
          jumpButton(99),
          jumpButton(5000),
        ],
      );

  final _scrollButtonStyle = ButtonStyle(
    padding: MaterialStateProperty.all(
      const EdgeInsets.symmetric(horizontal: 20, vertical: 0),
    ),
    minimumSize: MaterialStateProperty.all(Size.zero),
    tapTargetSize: MaterialTapTargetSize.shrinkWrap,
  );

  Widget scrollButton(int value) => TextButton(
        key: ValueKey<String>('Scroll$value'),
        onPressed: () {
          scrollTo(value);
        },
        child: Text('$value'),
        style: _scrollButtonStyle,
      );

  Widget jumpButton(int value) => TextButton(
        key: ValueKey<String>('Jump$value'),
        onPressed: () {
          jumpTo(value);
        },
        child: Text('$value'),
        style: _scrollButtonStyle,
      );

  void scrollTo(int index) async {
    if (index == 100) {
      await itemScrollController.scrollTo(
          index: 9, duration: const Duration(milliseconds: 10));
    }
    await itemScrollController
        .scrollTo(
            index: index,
            duration: scrollDuration,
            curve: Curves.easeInCubic,
            alignment: alignment)
        .then((value) {
      // _autoGetPosition();
    });
  }

  void anotherScrollTo(int index) async {
    itemScrollController.scrollToMax(
        curve: Curves.linear, duration: const Duration(milliseconds: 500));
  }

  void jumpTo(int index) =>
      itemScrollController.jumpTo(index: index, alignment: alignment);

  // void _getController() {}

  /// Generate item number [i].
  Widget item(int i, Orientation orientation) {
    return SizedBox(
      height: 200,
      child: Column(
        children: [
          Expanded(
            child: Container(
              color: Colors.grey[400],
              child: Center(
                child: Text('Item $i'),
              ),
            ),
          ),
          Container(
            height: 80,
            color: Colors.amber,
          )
        ],
      ),
    );
  }
}
8
likes
0
pub points
84%
popularity

Publisher

verified publisherayesavi.com

An Extension of scrollable_positioned_list with helper methods like scrollToMax,scrollToMin,jumpToMax and jumToMin it also supports listening to scroll notifications of the primary ScrollController

Homepage

License

unknown (license)

Dependencies

collection, flutter

More

Packages that depend on scrollable_positioned_list_extended