Let’s take a look at the renderings

In development, many scenarios will use the return to the top function. What about the return to the top button in Flutter?

First, we’ll write a button:

Well, I’m sure you can write this button.

Second, listen for page scrolling. Native we use a delegate to know how far a page is scrolling. How do we listen in a flutter? Look at the code:

	// The widget.controller is the external input of the scrolling 'controller' or page to be listened towidget.controller? .addListener(isScroll);void isScroll(){ final bool toShow = (widget.controller? .offset ??0) >
	        MediaQuery.of(context).size.height / 2;
	    if (toShow ^ shown) {
	      setState(() {
	      	// Controls whether to hide the top of the returnshown = toShow; }); }}Copy the code

The function of returning to the top is very simple, in the original is to change the offset, how to write in flutter?

// Do you know how to use easeIn animation?widget.controller? .animateTo(0.duration: Duration(milliseconds: 200),
                  curve: Curves.easeIn);
Copy the code

Notice that the back top button here is to float up, you have to use the Stack position and use the position of tourists:

/// Write the full widget for the button
import 'package:flutter/material.dart';

class BackToTop extends StatefulWidget {
  final ScrollController controller;
  /// pass in the distance to the bottom
  final double bottom;

  BackToTop(this.controller, {this.bottom});

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

class _BackToTopState extends State<BackToTop> {
  bool shown = false;

  @override
  void initState() {
    super.initState(); widget.controller? .addListener(isScroll); } @overridevoid dispose() {
    super.dispose(); widget.controller? .removeListener(isScroll); }void isScroll(){ final bool toShow = (widget.controller? .offset ??0) >
        MediaQuery.of(context).size.height / 2;
    if (toShow ^ shown) {
      setState(() {
        shown = toShow;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
        bottom: MediaQuery.of(context).padding.bottom + (widget.bottom ?? 40),
        right: 20.child: Offstage( offstage: ! shown,child: GestureDetector( onTap: () { widget.controller? .animateTo(0.duration: Duration(milliseconds: 200),
                  curve: Curves.easeIn);
            },
            child: Container(
                height: 44.width: 44.alignment: Alignment(0.0),
                decoration: new BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.all(Radius.circular(16)),
                    boxShadow: [
                      BoxShadow(
                          color: Color(0xFF000000).withOpacity(0.1),
                          blurRadius: 4.spreadRadius: 0),]),child: Column(
                  children: <Widget>[
                    Container(
                      margin: EdgeInsets.only(top: 4),
                      child: Icon(
                        Icons.vertical_align_top,
                        size: 20.color: Colors.black38,
                      ),
                    ),
                    Container(
                      margin: EdgeInsets.only(top: 0),
                      child: Text(
                        'Top'.style: TextStyle(fontSize: 10.color: Color(0xFFA1A6AA)),),)],))))); }}Copy the code

Now that buttons are out of the way, let’s talk about what to notice about the page that displays the buttons:

The only thing you need to notice is to pass in the controller, which must also be the controller of the current page:

/// The controller property should be assigned
controller: _controller,
Copy the code

Take a look at the code for the scrolling main page:

import 'package:flutter/material.dart';
import 'package:flutter_app/back_to_top.dart';

class BackTopListView extends StatefulWidget {
  @override
  _BackTopListViewState createState() => _BackTopListViewState();
}

class _BackTopListViewState extends State<BackTopListView> {
//
  final ScrollController _controller = ScrollController(keepScrollOffset: false);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: Text('Back to top page'),),body: SafeArea(
      	// Stack is used for this scenario. Otherwise, it will not cover the page, and the layout problem will not be discussed
        child: Stack(
          children: <Widget>[
            ListView.separated(
               /// The controller must be assigned to ensure that it is in the same controller
              controller: _controller,
              itemBuilder: (BuildContext context, int index) {
                return Container(
                    child: Container(
                        padding: EdgeInsets.all(10),
                        child: Text('Return top page Item$index'))); },separatorBuilder: (BuildContext context, int index) {
                return Divider();
              },
              itemCount: 100,),/// return to the top button, passing in the controllerBackToTop(_controller), ], ), ), ); }}Copy the code

Above, is not very simple? Have you learned?