Giter Site home page Giter Site logo

flutter_web_scrollbar_plugin's People

Contributors

cairacshields avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

flutter_web_scrollbar_plugin's Issues

Issue with syncing

How to make sure the web scrollbar and the scrolling of the page are synced? Right now if I scroll up and down with the mouse wheel, the scrolling works, but the web scrollbar doesn't follow along with the page movement.

Sugestion - > add some new functions to the library

I've closed my 2 issues because they were solved with this implementation:

This code contains:

tap on the handle to go to that place, and handle scrolling with the page.

For this to work, there is a little change in the _landingPageState from your pub.dev example.

Its in the end of this new code.

library flutter_web_scrollbar;

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
import 'package:flutter/scheduler.dart';

/// Welcome to the FlutterWebScrollBar Plugin!
/// In order to assist with using the plugin directly,
/// I've set up this introduction.
///
/// Before you begin implementing this scrollbar for
/// your web project, it's important to note that the plugin is
/// still under development.
///
/// We are actively working on things like mouse scroll detection, and
/// automatically determining the height of your page content.
///
/// Please feel free to file an issue report at the repository found here:
/// https://github.com/cairacshields/flutter_web_scrollbar_plugin

class FlutterWebScrollBar {
  static void registerWith(Registrar registrar) {
    final MethodChannel channel = MethodChannel(
        'plugins.flutter.io/flutter_web_scrollbar',
        const StandardMethodCodec(),
        registrar.messenger);
    final FlutterWebScrollBar instance = FlutterWebScrollBar();
    channel.setMethodCallHandler(instance.handleMethodCall);
  }

  Future<dynamic> handleMethodCall(MethodCall call) async {
    switch (call.method) {
      case 'flutter_web_scrollbar':
        ScrollController controller = call.arguments['controller'];
        Function scrollCallBack = call.arguments['scrollCallBack'];
        double proportion = call.arguments['proportion'];
        Color backgroundColor = call.arguments['scrollBarBackgroundColor'];
        double barWidth = call.arguments['scrollBarWidth'];
        Color handleColor = call.arguments['dragHandleColor'];
        double handleWidth = call.arguments['dragHandleWidth'];
        double handleHeight = call.arguments['dragHandleHeight'];
        double handleBorderRadius = call.arguments['dragHandleBorderRadius'];

        return FlutterWebScroller(
          controller,
          scrollCallBack,
          proportion,
          scrollBarBackgroundColor: backgroundColor,
          scrollBarWidth: barWidth,
          dragHandleColor: handleColor,
          dragHandleWidth: handleWidth,
          dragHandleHeight: handleHeight,
          dragHandleBorderRadius: handleBorderRadius,
        );
      default:
        throw PlatformException(
            code: 'Unimplemented',
            details:
                "The flutter_web_scrollbar plugin for web doesn't implement "
                "the method '${call.method}'");
    }
  }
}

class FlutterWebScroller extends StatefulWidget {
  final ScrollController controller;

  /// Required! CallBack function used to update the scrollable content with the new drag position

  final Function scrollCallBack;

  final double proportion;

  /// Optional: Background color of the scrollbar
  final Color scrollBarBackgroundColor;

  ///Optional: Width of the scrollbar
  final double scrollBarWidth;

  ///Optional: Color of the drag handle
  final Color dragHandleColor;

  ///Optional: Width of the drag handle
  final double dragHandleWidth;

  ///Optional: Height of the drag handle
  final double dragHandleHeight;

  ///Optional: Border Radius of the drag handle
  final double dragHandleBorderRadius;

  FlutterWebScroller(this.controller, this.scrollCallBack, this.proportion,
      {this.scrollBarBackgroundColor = Colors.black12,
      this.dragHandleColor = Colors.grey,
      this.scrollBarWidth = 20.0,
      this.dragHandleHeight = 40.0,
      this.dragHandleWidth = 15.0,
      this.dragHandleBorderRadius = 3.0});

  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _FlutterWebScrollerState();
  }
}

//static double _max = 0;
class _FlutterWebScrollerState extends State<FlutterWebScroller> {
  static double _offset = 0;

  _scrollListener() {
    setState(() {
      _offset = widget.controller.position.pixels / widget.proportion;
    });
  }

  @override
  void initState() {
    widget.controller.addListener(_scrollListener);
    SchedulerBinding.instance.addPostFrameCallback((_) {
      _updateScroll(0); // this is a workaround for the _max initial value of 0 
    });
    
    super.initState();
  }

  _updateScroll(double towhere) {
    widget.scrollCallBack(towhere);

    setState(() {
      if (towhere >= 0) {
        /// Update the offset of the drag handle to push it down or shift it up
        _offset = towhere;
        double maxHeight =
            MediaQuery.of(context).size.height - widget.dragHandleHeight;
        _offset = (_offset > maxHeight) ? maxHeight : _offset;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
        onTapDown: (TapDownDetails details) =>
            _updateScroll(details.globalPosition.dy),
        child: Container(
            alignment: Alignment.centerRight,
            height: MediaQuery.of(context).size.height,
            width: widget.scrollBarWidth,
            margin: EdgeInsets.only(
                left:
                    MediaQuery.of(context).size.width - widget.scrollBarWidth),
            decoration: BoxDecoration(color: widget.scrollBarBackgroundColor),
            child: Container(
              alignment: Alignment.topCenter,
              child: GestureDetector(
                child: Container(
                  height: widget.dragHandleHeight,
                  width: widget.dragHandleWidth,
                  margin: EdgeInsets.only(left: 5.0, right: 5.0, top: _offset),
                  decoration: BoxDecoration(
                      color: widget.dragHandleColor,
                      borderRadius: BorderRadius.all(
                          Radius.circular(widget.dragHandleBorderRadius))),
                ),
                onVerticalDragUpdate: (dragUpdate) {
                  final _towhere = dragUpdate.globalPosition.dy;
                  _updateScroll(_towhere);

                  /// Send the new drag details to the callback in order to properly update the scrollable content position
                },
              ),
            )));
  }
}

Example with fixes:

class _LandingPageState extends State<LandingPage> {
  ScrollController _controller;
  double _max = 0;
  double _screenSize = 0;
  @override
  void initState() {
    //Initialize the  scrollController
    _controller = ScrollController();
    super.initState();
  }

  void scrollCallBack(double dragUpdate) {
    setState(() {
      // Note: 3.5 represents the theoretical height of all my scrollable content. This number will vary for you.
      _controller.position.moveTo(dragUpdate * _max / _screenSize);
    });
  }

  @override
  Widget build(BuildContext context) {
    _screenSize = MediaQuery.of(context).size.height;
    _max = _controller.hasClients ? _controller.position.maxScrollExtent : 0;
    return Scaffold(
      backgroundColor: Colors.white,
      body: Stack(
        children: [
          Container(
            child: SingleChildScrollView(
              //Assign the controller to my scrollable widget
              controller: _controller,
              child: Column(
                children: [
                  Container(
   
```                 height: MediaQuery.of(context).size.height,
                    width: MediaQuery.of(context).size.width,
                    color: Colors.black,
                  ),
                  Container(
                    height: MediaQuery.of(context).size.height,
                    width: MediaQuery.of(context).size.width,
                    color: Colors.red,
                  ),
                  Container(
                    height: MediaQuery.of(context).size.height,
                    width: MediaQuery.of(context).size.width,
                    color: Colors.green,
                  ),
                  Container(
                    height: MediaQuery.of(context).size.height,
                    width: MediaQuery.of(context).size.width,
                    color: Colors.blue,
                  ),
                ],
              ),
            ),
          ),
          FlutterWebScroller(
            _controller,
            //Pass a reference to the ScrollCallBack function into the scrollbar
            scrollCallBack,
            _max / _screenSize,
            //Add optional values
            scrollBarBackgroundColor: Colors.white,
            scrollBarWidth: 20.0,
            dragHandleColor: Colors.red,
            dragHandleBorderRadius: 2.0,
            dragHandleHeight: 40.0,
            dragHandleWidth: 15.0,
          ),
        ],
      ),
    );
  }
}

Sugestion - Automatic max size of the scroll

for this implementation i've used the new vars _max and _screensize on the main screen of the example:

class _LandingPageState extends State<LandingPage> {
  ScrollController _controller;
  double _max = 0;
  double _screenSize = 0;
  @override
  void initState() {
    //Initialize the  scrollController
    _controller = ScrollController();
    super.initState();
  }

  void scrollCallBack(double dragUpdate) {
    setState(() {
      // Note: 3.5 represents the theoretical height of all my scrollable content. This number will vary for you.
      _controller.position.moveTo(dragUpdate * _max / _screenSize);
    });
  }

  @override
  Widget build(BuildContext context) {
    _screenSize = MediaQuery.of(context).size.height;
    _max = _controller.hasClients ? _controller.position.maxScrollExtent : 0;

Sugestion - Add on tap bar -> the page goes to that place

I've tried changing your code a little to implement this function. Its something like wrapping the container holding the bar with a gesturedetector too:

And changing a little the function:

class _FlutterWebScrollerState extends State<FlutterWebScroller> {

  static double _offset = 0;

  _updateScroll(double towhere) {
    widget.scrollCallBack(towhere);

    setState(() {
      if (towhere >= 0) {
        /// Update the offset of the drag handle to push it down or shift it up
        _offset = towhere;
        double maxHeight =
            MediaQuery.of(context).size.height - widget.dragHandleHeight;
        _offset = (_offset > maxHeight) ? maxHeight : _offset;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
        onTapDown: (TapDownDetails details) =>
            _updateScroll(details.globalPosition.dy),
        child: Container(
            alignment: Alignment.centerRight,
            height: MediaQuery.of(context).size.height,
            width: widget.scrollBarWidth,
            margin: EdgeInsets.only(
                left:
                    MediaQuery.of(context).size.width - widget.scrollBarWidth),
            decoration: BoxDecoration(color: widget.scrollBarBackgroundColor),
            child: Container(
              alignment: Alignment.topCenter,
              child: GestureDetector(
                child: Container(
                  height: widget.dragHandleHeight,
                  width: widget.dragHandleWidth,
                  margin: EdgeInsets.only(left: 5.0, right: 5.0, top: _offset),
                  decoration: BoxDecoration(
                      color: widget.dragHandleColor,
                      borderRadius: BorderRadius.all(
                          Radius.circular(widget.dragHandleBorderRadius))),
                ),
                onVerticalDragUpdate: (dragUpdate) {
                  final _towhere = dragUpdate.globalPosition.dy;
                  _updateScroll(_towhere);

                  /// Send the new drag details to the callback in order to properly update the scrollable content position
                },
              ),
            )));

 }
}

the new scrollcallback on the main screen(on your example):

  void scrollCallBack(double dragUpdate) {
    setState(() {
      // Note: 3.5 represents the theoretical height of all my scrollable content. This number will vary for you.
      _controller.position.moveTo(dragUpdate * 3.5);
    });
  }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.