(两百二十八)学习“给Android开发者的Flutter指南”(二)

继续学习https://flutter.cn/docs/get-started/flutter-for/android-devs#how-do-i-use-a-canvas-to-drawpaint

 

目录

视图 (Views)

如何使用 Canvas 进行绘制?

如何创建自定义 Widget?

Intents

Intent 在 Flutter 中的对应概念是什么?


视图 (Views)

如何使用 Canvas 进行绘制?

在 Android 中,你可以使用 CanvasDrawable 将图片和形状绘制到屏幕上。Flutter 也有一个类似于 Canvas 的 API,因为它基于相同的底层渲染引擎 Skia。因此,在 Flutter 中用画布 (canvas) 进行绘制对于 Android 开发者来说是一件非常熟悉的工作。

Flutter 有两个帮助你用画布 (canvas) 进行绘制的类:CustomPaintCustomPainter,后者可以实现自定义的绘制算法。

如果想学习在 Flutter 中如何实现一个签名功能,可以查看 Collin 在 Custom Paint 上的回答。

import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(home: DemoApp()));

class DemoApp extends StatelessWidget {
  Widget build(BuildContext context) => Scaffold(body: Signature());
}

class Signature extends StatefulWidget {
  SignatureState createState() => SignatureState();
}

class SignatureState extends State<Signature> {
  List<Offset> _points = <Offset>[];
  Widget build(BuildContext context) {
    return GestureDetector(
      onPanUpdate: (DragUpdateDetails details) {
        setState(() {
          RenderBox referenceBox = context.findRenderObject();
          Offset localPosition =
              referenceBox.globalToLocal(details.globalPosition);
          _points = List.from(_points)..add(localPosition);
        });
      },
      onPanEnd: (DragEndDetails details) => _points.add(null),
      child: CustomPaint(
        painter: SignaturePainter(_points),
        size: Size.infinite,
      ),
    );
  }
}

class SignaturePainter extends CustomPainter {
  SignaturePainter(this.points);
  final List<Offset> points;
  void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..color = Colors.black
      ..strokeCap = StrokeCap.round
      ..strokeWidth = 5.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);
    }
  }

  bool shouldRepaint(SignaturePainter other) => other.points != points;
}

效果是一个画布,肯定手动画出黑色线条

 

如何创建自定义 Widget?

在 Android 中,一般通过继承 View 类,或者使用已有的视图类,再覆写或实现可以达到特定效果的方法。

在 Flutter 中,通过 组合 更小的 Widget 来创建自定义 Widget(而不是继承它们)。这和 Android 中实现一个自定义的 ViewGroup 有些类似,所有的构建 UI 的模块代码都在手边,不过由你提供不同的行为—例如,自定义布局 (layout) 逻辑。

举例来说,你该如何创建一个在构造器接收标签参数的 CustomButton?你要组合 RaisedButton 和一个标签来创建自定义按钮,而不是继承 RaisedButton

class CustomButton extends StatelessWidget {
  final String label;

  CustomButton(this.label);

  @override
  Widget build(BuildContext context) {
    return RaisedButton(onPressed: () {}, child: Text(label));
  }
}

然后就像使用其它 Flutter Widget 一样使用 CustomButton

@override
Widget build(BuildContext context) {
  return Center(
    child: CustomButton("Hello"),
  );
}

大概写了下

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: Center(
          child: CustomButton("Hello"),
        ),
      ),
    );
  }
}

class CustomButton extends StatelessWidget {
  final String label;

  CustomButton(this.label);

  @override
  Widget build(BuildContext context) {
    return RaisedButton(onPressed: () {}, child: Text(label));
  }
}

 

Intents

Intent 在 Flutter 中的对应概念是什么?

在 Android 中,Intent 主要有两个使用场景:在 Activity 之前进行导航,以及组件间通信。 Flutter 却没有 intent 这样的概念,但是你依然可以通过原生集成 (插件) 来启动 intent。

Flutter 实际上并没有 Activity 和 Fragment 的对应概念。在 Flutter 中你需要使用 NavigatorRoute 在同一个 Activity 内的不同界面间进行跳转。

Route 是应用内屏幕和页面的抽象,Navigator 是管理路径 route 的工具。一个 route 对象大致对应于一个 Activity,但是它的含义是不一样的。Navigator 可以通过对 route 进行压栈和弹栈操作实现页面的跳转。Navigator 的工作原理和栈相似,你可以将想要跳转到的 route 压栈 (push()),想要返回的时候将 route 弹栈 (pop())。

在 Android 中,在应用的 AndroidManifest.xml 文件中声明 Activity。

在 Flutter 中,你有多种不同的方式在页面间导航:

  • 定义一个 route 名字的 Map。(MaterialApp)

  • 直接导航到一个 route。(WidgetApp)

下面的例子创建了一个 Map。

void main() {
  runApp(MaterialApp(
    home: MyAppHome(), // becomes the route named '/'
    routes: <String, WidgetBuilder> {
      '/a': (BuildContext context) => MyPage(title: 'page A'),
      '/b': (BuildContext context) => MyPage(title: 'page B'),
      '/c': (BuildContext context) => MyPage(title: 'page C'),
    },
  ));
}

通过将 route 名压栈 (push) 到 Navigator 中来跳转到这个 route。

Navigator.of(context).pushNamed('/b');

Intent 的另一种常见的使用场景是调用外部的组件,例如相机或文件选择器。对于这种情况,你需要创建一个原生平台集成(或者使用 已有的插件

想要学习如何创建一个原生平台集成,请查看 开发包和插件

这里本地试了下没搞懂怎么用。。。

百度搜了下参考 https://blog.csdn.net/u013000152/article/details/80940682

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    home: MyAppHome(), // becomes the route named '/'
    routes: <String, WidgetBuilder> {
      '/a': (BuildContext context) => MyPage('page A'),
      '/b': (BuildContext context) => MyPage('page B'),
      '/c': (BuildContext context) => MyPage('page C'),
    },
  ));
}

class MyAppHome extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return new PageState();
  }
}


class PageState extends State<MyAppHome> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new Center(child: new RaisedButton(onPressed: _pushPage,child: new Text("跳转"),),),
    );
  }
  _pushPage(){
    Navigator.of(context).pushNamed('/b');
  }
}

class MyPage extends StatelessWidget{
  final String title;

  MyPage(this.title);

  @override
  Widget build(BuildContext context) {
    return RaisedButton(onPressed: () {}, child: Text(title));
  }
}

这样就可以跳转了,Navigator.of(context).pushNamed('/b');这句是放在点击事件里的

class RandomWordsState extends State<MyAppHome> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Flutter Intent test'),
        actions: <Widget>[
          new IconButton(icon: const Icon(Icons.list), onPressed: _pushSaved),
        ],
      ),
    );
  }

  _pushSaved(){
    Navigator.of(context).pushNamed('/b');
  }
}

PageState可以改成之前学的RandomWordsState里面的,改成actionbar

稍微总结下,这里只要是捎带介绍了下Android和flutter的概念差异,方便更快入门

 

 

相关推荐
©️2020 CSDN 皮肤主题: 鲸 设计师:meimeiellie 返回首页