What is the right way to add a sized PageView in Flutter?

Ralph Bergmann

I try to add a PageView which doesn't fill the whole screen.

To do that I putted the PageView inside a Column:

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(),
      body: new Column(
        children: <Widget>[
          new SizedBox(height: 100.0, child: new Center(child: new Text("sticky header"))),
          new Expanded(
            child: new PageView(
              children: <Widget>[
                new Container(
                  color: Colors.red,
                  child: new Padding(
                    padding: const EdgeInsets.all(50.0),
                    child: new _Painter(),
                  ),
                ),
                new Container(
                  color: Colors.green,
                  child: new Padding(
                    padding: const EdgeInsets.all(50.0),
                    child: new _Painter(),
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

This works so far.

Each PageView has a _Painter which has a RenderBox to paint something.

And here comes my problem: I use the handleEvent method to detect drag events but the y position is wrong. You can see that the drawn line is not where I touched the screen (the transparent bubble).

enter image description here

How can I fix this? Do I have to calculate the correct y position myself?

You can find the full source here.

Update

globalToLocal fixed the problem halfway but I still have to include the padding in the calculation. Is there a way to get the padding of a widget?

void _handleDragUpdate(DragUpdateDetails details) {
  final pos = globalToLocal(details.globalPosition);
  _currentPath?.lineTo(pos.dx + 50.0, pos.dy + 50.0);
  markNeedsPaint();
}

Bonus Points

When I drag the PageView left and right my _PainterRenderBox forgets the drawn lines. Where is the best place to remember this lines? Store them in the _Painter or in the _MyHomePageState?

Hemanth Raj

Something that you are missing is to convert the globalPosition into localPosition with respect to the RenderBox. You can achieve it like

// onDragUpdate with the Painting Context
RenderBox referenceBox = context.findRenderObject();
Offset localPosition = referenceBox.globalToLocal(details.globalPosition);
// then use the localPosition to draw

Example usage for your use case as in here:

class _PainterRenderBox extends RenderBox {
  final _lines = new List<Path>();
  PanGestureRecognizer _drag;
  Path _currentPath;

  // variable to store padding
  Offset padding;

  _PainterRenderBox() {
    final GestureArenaTeam team = new GestureArenaTeam();
    _drag = new PanGestureRecognizer()
      ..team = team
      ..onStart = _handleDragStart
      ..onUpdate = _handleDragUpdate
      ..onEnd = _handleDragEnd;
  }

  @override
  bool get sizedByParent => true;

  @override
  bool hitTestSelf(Offset position) => true;

  @override
  handleEvent(PointerEvent event, BoxHitTestEntry entry) {
    assert(debugHandleEvent(event, entry));
    if (event is PointerDownEvent) {
      _drag.addPointer(event);
    }
  }

  @override
  paint(PaintingContext context, Offset offset) {
    final Canvas canvas = context.canvas;

    // update padding
    padding = offset;

    final Paint paintBorder = new Paint()
      ..strokeWidth = 1.0
      ..style = PaintingStyle.stroke
      ..color = Colors.white.withAlpha(128);
    canvas.drawRect(offset & size, paintBorder);

    final Paint paintPath = new Paint()
      ..strokeWidth = 5.0
      ..style = PaintingStyle.stroke
      ..color = Colors.white;
    _lines.forEach((path) {
      canvas.drawPath(path, paintPath);
    });
  }

  // check if the point lies inside drawable area
  bool _canDraw(Offset offset){
    return (padding & size).contains(offset);
  }

  void _handleDragStart(DragStartDetails details) {
    _currentPath = new Path();
    Offset point = globalToLocal(details.globalPosition); // convert globalPosition to localPosition
    point = padding + point; // add the padding to localPosition if any
    // check if point lies inside drawable area and then markNeedsPaint
    if(_canDraw(point)){
      _currentPath?.moveTo(point.dx, point.dy);
      _lines.add(_currentPath);
      markNeedsPaint();
    }
  }

  void _handleDragUpdate(DragUpdateDetails details) {
    Offset point = globalToLocal(details.globalPosition); // convert globalPosition to localPosition
    point = padding + point; // add the padding to localPosition if any
    // check if point lies inside drawable area and then markNeedsPaint
    if(_canDraw(point)){
      _currentPath?.lineTo(point.dx, point.dy);
      markNeedsPaint();
    }
  }

  void _handleDragEnd(DragEndDetails details) {
    _currentPath = null;
    markNeedsPaint();
  }
}

There is a question with a similar use case which allows the user to sign on the screen. Hope that might help you to know how to keep track of path. You can take a look at it here.

Hope that helps!

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Java

Flutter PageView - Show preview of page on left and right

From Dev

What is the right way to add percentages to a service/product?

From Java

What is the right way to add data to an existing named volume in Docker?

From Dev

What is the right way to add files to userdata.img in AOSP?

From Dev

What is the right way to add a variable where-clause to this update function

From Dev

What's the right way to add even or odd numbers in this assembly code

From Dev

What is the right way to add files to userdata.img in AOSP?

From Dev

What is the right way to add json-simple library on intellij?

From Dev

What is the right way to add function handles recursive and see the right output after printing it?

From Java

What is the correct way to add date picker in flutter app?

From Dev

What is the right way to use "instanceof"?

From Dev

What is the right way to initialize a QList?

From Dev

what is the right way to downgrade kernel

From Dev

What is the right way to use QQuickImageProvider?

From Dev

What is the 'right' way to resize a SymbolIcon?

From Dev

what is the right way to downgrade kernel

From Dev

What is the right way to initialize a QList?

From Dev

What is the right way to use "instanceof"?

From Dev

What is the right way to explain this code?

From Dev

What is right way to work with tableview?

From Dev

What is a good way to allocate a sized string buffer on the stack?

From Dev

What is the best way to have a background be 4 equally sized images?

From Dev

What is the right way to add gesture detection to a custom UIView used in a reusable UITableCellView?

From Dev

Is there a way to add shred to right-click menu?

From Dev

Right way to add permissions : titanium android appcelerator

From Dev

Right way to add table column in laravel 4

From Dev

Is there a way to add shred to right-click menu?

From Dev

What is the right way of creating circle animation?

From Dev

What is the right way to use Java executor?

Related Related

  1. 1

    Flutter PageView - Show preview of page on left and right

  2. 2

    What is the right way to add percentages to a service/product?

  3. 3

    What is the right way to add data to an existing named volume in Docker?

  4. 4

    What is the right way to add files to userdata.img in AOSP?

  5. 5

    What is the right way to add a variable where-clause to this update function

  6. 6

    What's the right way to add even or odd numbers in this assembly code

  7. 7

    What is the right way to add files to userdata.img in AOSP?

  8. 8

    What is the right way to add json-simple library on intellij?

  9. 9

    What is the right way to add function handles recursive and see the right output after printing it?

  10. 10

    What is the correct way to add date picker in flutter app?

  11. 11

    What is the right way to use "instanceof"?

  12. 12

    What is the right way to initialize a QList?

  13. 13

    what is the right way to downgrade kernel

  14. 14

    What is the right way to use QQuickImageProvider?

  15. 15

    What is the 'right' way to resize a SymbolIcon?

  16. 16

    what is the right way to downgrade kernel

  17. 17

    What is the right way to initialize a QList?

  18. 18

    What is the right way to use "instanceof"?

  19. 19

    What is the right way to explain this code?

  20. 20

    What is right way to work with tableview?

  21. 21

    What is a good way to allocate a sized string buffer on the stack?

  22. 22

    What is the best way to have a background be 4 equally sized images?

  23. 23

    What is the right way to add gesture detection to a custom UIView used in a reusable UITableCellView?

  24. 24

    Is there a way to add shred to right-click menu?

  25. 25

    Right way to add permissions : titanium android appcelerator

  26. 26

    Right way to add table column in laravel 4

  27. 27

    Is there a way to add shred to right-click menu?

  28. 28

    What is the right way of creating circle animation?

  29. 29

    What is the right way to use Java executor?

HotTag

Archive