wtorek, 30 Październik 2018

flutter - build native apps

Flutter – Rysowanie

We wpisie przyjrzymy się jak stworzyć prostą aplikację do rysowania we frameworku Flutter.

Po stworzeniu nowego projektu z wybraną przez siebie nazwą przy użyciu komendy „flutter create nazwa_projektu” i uruchomieniu komendy „flutter run” powinniśmy zobaczyć na ekranie naszego telefonu (jeśli korzystamy z telefonu podpiętego poprzez USB) lub ekranie emulatora napis „Hello World”.

Następnie przechodzimy do „pliku main.dart” w folderze „lib”, cały zawarty w nim kod podmieniamy na poniższy.


import 'package:flutter/material.dart';
import 'dart:math';

void main() => runApp(new MaterialApp(
      home: new HomePage()
));

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => new _HomePageState();
}


class _HomePageState extends State {
  List _points = [];

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Container(
        child: new GestureDetector(
          onPanUpdate: (DragUpdateDetails details) {
            setState(() {
              RenderBox object = context.findRenderObject();
              Offset _localPosition =
                  object.globalToLocal(details.globalPosition);
              _points = new List.from(_points)..add(_localPosition);
            });
          },
          onPanEnd: (DragEndDetails details) => _points.add(null),
          child: new CustomPaint(
            painter: new Painting(points: _points),
            size: Size.infinite,
          ),
        ),
      ),
    );
  }
}

class Painting extends CustomPainter {
  List points;
  
  Painting({this.points});

  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = new Paint()
      ..color = Colors.pink
      ..strokeCap = StrokeCap.round
      ..strokeWidth = 20.0;


    for (int i = 0; i < points.length - 1; i++) {
      if (points[i] != null && points[i + 1] != null) {
        canvas.drawLine(points[i], points[i + 1], paint);
      }
    }
  }

  @override
  bool shouldRepaint(Painting oldDelegate) => oldDelegate.points != points;
}

Krótkie wyjaśnienie niektórych fragmentów kodu, w tym miejscu przy pomocy GestureDetector jak sama nazwa wskazuje jesteśmy w stanie obsłużyć zdarzenia zachodzące za pomocą gestów, „onPanUpdate” wykrywa kiedy przesuwamy naszym palcem po ekranie, przy pomocy tej funkcji aktualizujemy listę punktów podczas przesuwania, „onPanEnd” używamy kiedy kończymy interakcję z ekranem.



child: new GestureDetector(
  onPanUpdate: (DragUpdateDetails details) {
    setState(() {
      RenderBox object = context.findRenderObject();
      Offset _localPosition =
          object.globalToLocal(details.globalPosition);
      _points = new List.from(_points)..add(_localPosition);
    });
  },
  onPanEnd: (DragEndDetails details) => _points.add(null),
  child: new CustomPaint(
    painter: new Painting(points: _points),
    size: Size.infinite,
  ),
),

W tej sekcji wykorzystujemy nasze punkty do wyrysowania linii z danych zebranych przy pomocy gestów a także nadajemy naszym liniom style, między innymi kolor czy grubość.


class Painting extends CustomPainter {
  List points;
  
  Painting({this.points});

  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = new Paint()
      ..color = Colors.pink
      ..strokeCap = StrokeCap.round
      ..strokeWidth = 20.0;


    for (int i = 0; i < points.length - 1; i++) {
      if (points[i] != null && points[i + 1] != null) {
        canvas.drawLine(points[i], points[i + 1], paint);
      }
    }
  }

  @override
  bool shouldRepaint(Painting oldDelegate) => oldDelegate.points != points;
}

Po uruchomieniu aplikacji, zobaczymy biały ekran, po którym możemy rozpocząć rysowanie

list

Zdecydowanie warto byłoby dodać możliwość wyczyszczenia ekranu, dlatego do tego celu dodamy przycisk „floatingActionButton”, umieścimy go w dolnym prawym rogu ekranu


class _HomePageState extends State {
  List _points = [];

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Container(
        child: new GestureDetector(
          onPanUpdate: (DragUpdateDetails details) {
            setState(() {
              RenderBox object = context.findRenderObject();
              Offset _localPosition =
                  object.globalToLocal(details.globalPosition);
              _points = new List.from(_points)..add(_localPosition);
            });
          },
          onPanEnd: (DragEndDetails details) => _points.add(null),
          child: new CustomPaint(
            painter: new Painting(points: _points),
            size: Size.infinite,
          ),
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        backgroundColor: Colors.pink,
        child: new Icon(Icons.clear),
        onPressed: () => _points.clear(),
      ),
    );
  }
}
list

Ożywimy naszą aplikację poprzez dodanie funkcji random i losowe dobieranie styli przy każdej próbowanie rysowania. Dzięki temu, że wcześniej zaimportowaliśmy już bibliotekę math, musimy dodać do naszej aplikacje listy z nowymi stylami.



class Painting extends CustomPainter {
  List points;
  
  Painting({this.points});

  final _random = new Random();

  var brushColors = [Colors.red, Colors.blue, Colors.green, Colors.pink, Colors.black, Colors.yellow, Colors.orange];
  var brushCap = [StrokeCap.butt, StrokeCap.round, StrokeCap.square];
  var brushSize = [5.0, 10.0, 15.0, 20.0, 25.0];
  

  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = new Paint()
      ..color = brushColors[_random.nextInt(brushColors.length)]
      ..strokeCap = brushCap[_random.nextInt(brushCap.length)]
      ..strokeWidth = brushSize[_random.nextInt(brushSize.length)];


    for (int i = 0; i < points.length - 1; i++) {
      if (points[i] != null && points[i + 1] != null) {
        canvas.drawLine(points[i], points[i + 1], paint);
      }
    }
  }

  @override
  bool shouldRepaint(Painting oldDelegate) => oldDelegate.points != points;
}

Teraz po każdym dodanym punkcie do listy, nasza linia będzie zmieniać w losowy sposób swoje style

Back to home
Flutter – Nawigacja pomiędzy widokami

Nawigacja pomiędzy widokami we frameworku Flutter.

Read more...
Alternatywne JavaScriptowe Frameworki

W JavaScriptowym świecie poza frameworkami React, Angular które podzieliły po między siebie popularność, a goniącym je Vue.js jest jeszcze miejsce na inne, mniej skompilowane frameworki, które nie zostały jeszcze dostrzeżone przez szersze grono ludzi.

Read more...
Flutter – pobieranie danych w formacie JSON

W tym wpisie zapoznamy się jak w prosty sposób pobrać dane w formacie JSON.

Read more...