Jonas
Jonas

Reputation: 21

Listen for Start ScrollController on CustomScrollView

In my project I have a project where I only want to set the visibility of an action button if the screen is scrolled all the way up.

The code that I have right now works fine but it will trigger the code as soon as the screen begins to scroll up - and it is really not what I want.

So how can I fix this ?

Below is my code as on demand

class AccountPage extends StatefulWidget with NavigationStates {
  @override
  _AccountPage createState() => _AccountPage();
}

class _AccountPage extends State<AccountPage> {
  String searchQuery = '';
  ScrollController _controller;

  bool sliverActionsHidden = true;

  // Tracking search query.
  void _updateSearchQuery(String query) {
    setState(
      () {
        searchQuery = query;
      },
    );
  }

  // Listening for user scroll on screen.
  void _scrollListener() {
    if (_controller.offset <= _controller.position.minScrollExtent &&
        !_controller.position.outOfRange) {
      setState(() {
        sliverActionsHidden = false;
        print('Reach the top');
      });
    }
    else {
      setState(() {
        sliverActionsHidden = true;
        print('Reach the bottom');
      });
    }
  }

  @override
  void initState() {
    _controller = ScrollController();
    _controller.addListener(_scrollListener);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    /* Action IconButtons ----------------------------------------------- */
    final actionButtons = <Widget>[
      IconButton(
        icon: Icon(Icons.filter_list),
        onPressed: () {
          print('Filter');
        },
      ),
      IconButton(
        icon: Icon(Icons.more_vert),
        onPressed: () {
          print('More Settings');
        },
      ),
    ];

    /* Material Appbar ----------------------------------------------- */
    final PreferredSizeWidget appBar = SearchBar(
      canSearch: true,
      query: searchQuery,
      searchQuery: (value) {
        _updateSearchQuery(value);
        print("Listening for search query : $value");
      },
      // Action Icons
      actions: actionButtons,
    );

    /* Sliver Appbar ----------------------------------------------- */
    final sliverAppBar = SliverAppBar(
      pinned: true,
      expandedHeight: MediaQuery.of(context).size.height * 0.2,
      backgroundColor: Theme.of(context).primaryColor,
      flexibleSpace: FlexibleSpaceBar(
        // Searchbar
        background: Column(
          children: <Widget>[
            appBar,
          ],
        ),
        // Page Title
        title: Text(
          AppStrings.accountTitle,
          style: Theme.of(context).textTheme.title.copyWith(
                color: CustomColors().novaWhite,
              ),
        ),
      ),
      // Action Buttons
      actions: sliverActionsHidden ? actionButtons : <Widget>[],
    );

    /* Page Content ----------------------------------------------- */
    final bodyContent = SafeArea(
      bottom: false,
      child: CustomScrollView(
        controller: _controller,
        slivers: <Widget>[
          sliverAppBar,
          SliverToBoxAdapter(
            child: Container(
              height: MediaQuery.of(context).size.height,
              padding: EdgeInsets.all(Constants.paddingXY_32),
              decoration: BoxDecoration(
                color: Theme.of(context).scaffoldBackgroundColor,
              ),
              // Page content begins here...
              child: Text(searchQuery.toString()),
            ),
          ),
        ],
      ),
    );

    /* Scaffold ----------------------------------------------- */
    return Scaffold(
      body: bodyContent,
      backgroundColor: Theme.of(context).primaryColor,
    );
  }
}

Upvotes: 2

Views: 2014

Answers (1)

F Perroch
F Perroch

Reputation: 2215

You can check if the maxScrollExtent value of the scroll position is reached :

void _scrollListener() {
  if (_controller.offset == _controller.position.maxScrollExtent) {
    setState(() {
      sliverActionsHidden = true;
      print('Reach the top');
    });
  } else {
    setState(() {
      sliverActionsHidden = false;
      print('Reach the bottom');
    });
  }
}

Upvotes: 1

Related Questions