bluenile
bluenile

Reputation: 6029

How to draw line on a container when a button is tapped

I'm still learning Flutter and do not fully understand CustomPainter.

The following code does not draw line on the Container that is nested in the Column. I want to draw Line when the Draw Line button is tapped.

While debugging the code I can see that the CustomPainter is called but the line is not drawn.

import 'package:flutter/material.dart';
void main() {
  runApp(
    MaterialApp(
      home: Home(),
    ),
  );
}
class Home extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _HomeState();
  }
}
class _HomeState extends State<Home> {
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: AppBar(
        title: Text('Draw Line'),
      ),
      backgroundColor: Colors.white,
      body: Column(
        children: <Widget>[
          SizedBox(
            height: 200,
            width: 200,
            child: Container(),
          ),
          RaisedButton(
            onPressed: () {
              CustomPaint(
                painter: LinePainter(),
              );
            },
            child: Text('Draw Line'),
          )
        ],
      ),
    );
  }
}
class LinePainter extends CustomPainter {
  Paint _paint;
  LinePainter() {
    _paint = Paint()
      ..color = Colors.amber
      ..strokeWidth = 8.0;
  }
  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawLine(Offset(0.0, 0.0), Offset(size.width, size.height), _paint);
  }
  @override
  bool shouldRepaint(LinePainter oldDelegate) {
    return true;
  }
}

Upvotes: 0

Views: 1639

Answers (1)

easeccy
easeccy

Reputation: 5086

Your widget hierarchy was in wrong order. You need to use CustomPainter as parent widget. I also implemented a simple logic to pass the second point as Offset to the painter. You can also pass a simple boolean variable to control "painted" and "clean" states if you want.

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Home(),
    ),
  );
}

class Home extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _HomeState();
  }
}

class _HomeState extends State<Home> {
  Offset _offset = Offset(0, 0);

  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: AppBar(
        title: Text('Draw Line'),
      ),
      backgroundColor: Colors.white,
      body: Column(
        children: <Widget>[
          SizedBox(
            height: 200,
            width: 200,
            child: Container(),
          ),
          CustomPaint(
            foregroundPainter: LinePainter(_offset),
            child: RaisedButton(
              onPressed: () {setState(() {
                _offset = Offset(60, 60);
              });},
              child: Text("Draw Line"),
            ),
          )
        ],
      ),
    );
  }
}

class LinePainter extends CustomPainter {
  Paint _paint;
  Offset _offset;

  LinePainter(Offset offset) {
    _offset = offset;
    _paint = Paint()
      ..color = Colors.amber
      ..strokeWidth = 8.0;
  }

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawLine(Offset(0, 0), _offset, _paint);
  }

  @override
  bool shouldRepaint(LinePainter oldDelegate) {
    return true;
  }
}

Upvotes: 2

Related Questions