美文网首页
Flutter开发之自定义view,widget

Flutter开发之自定义view,widget

作者: 我打小就帅 | 来源:发表于2020-03-04 23:34 被阅读0次

    为了满足我们自身的开发需求,很多时候就需要我们自定动手制作东西,也就是所谓的自定义view,那么我们一起学习下flutter的自定义view吧

    本人理解flutter的自定义view可以归为两类:
    1,已有控件(widget)的继承,组合
    2,自定义绘制widget,也就是利用paint,cavans等进行绘制视图。

    1,先来示例第一种吧

    我们做一个自定义的dialog,这个dialog是继承原生自带的Dialog,并且组合其他的控件一起的。

    import 'dart:ui';
    import 'package:flutter/material.dart';
    
     
    class TestMessageDialog extends Dialog {
      BuildContext mContext;
      String title;
      String message;
      String negativeText;
      String positiveText;
      Function onCloseEvent;
      Function onPositivePressEvent;
    
      TestMessageDialog({
        Key key,
        @required this.title,
        @required this.message,
        this.negativeText,
        this.positiveText,
        this.onPositivePressEvent,
        @required this.onCloseEvent,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        mContext=context;
        return GestureDetector(
            onTap: () {
              Navigator.pop(context);
            },
            child: WillPopScope(
              onWillPop: () {
                _onNavigationClickEvent();
                return Future.value(false);
              },
              child: Material(
                color: Colors.transparent,
    
                child: Stack(
                  fit: StackFit.expand,
                  children: <Widget>[
                    GestureDetector(onTap: _onNavigationClickEvent),
                    _buildContentView(), //构建具体的对话框布局内容
                  ],
                ),
              ),
            ));
    
      }
    
      void _onNavigationClickEvent(){
    
        Navigator.pop(mContext);
      }
      Widget _buildContentView(){
        return new Padding(
          padding: const EdgeInsets.all(15.0),
          child: new Material(
            type: MaterialType.transparency,
            child: new Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new Container(
                  decoration: ShapeDecoration(
                    color: Color(0xffffffff),
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.all(
                        Radius.circular(8.0),
                      ),
                    ),
                  ),
                  margin: const EdgeInsets.all(12.0),
                  child: new Column(
                    children: <Widget>[
                      new Padding(
                        padding: const EdgeInsets.all(10.0),
                        child: new Stack(
                          alignment: AlignmentDirectional.centerEnd,
                          children: <Widget>[
                            new Center(
                              child: new Text(
                                title,
                                style: new TextStyle(
                                  fontSize: 19.0,
                                ),
                              ),
                            ),
                            new GestureDetector(
                              onTap: this.onCloseEvent,
                              child: new Padding(
                                padding: const EdgeInsets.all(5.0),
                                child: new Icon(
                                  Icons.close,
                                  color: Color(0xffe0e0e0),
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),
                      new Container(
                        color: Color(0xffe0e0e0),
                        height: 1.0,
                      ),
                      new Container(
                        constraints: BoxConstraints(minHeight: 180.0),
                        child: new Padding(
                          padding: const EdgeInsets.all(12.0),
                          child: new IntrinsicHeight(
                            child: new Text(
                              message,
                              style: TextStyle(fontSize: 16.0),
                            ),
                          ),
                        ),
                      ),
                      this._buildBottomButtonGroup(),
                    ],
                  ),
                ),
              ],
            ),
          ),
        );
      }
    
    
      Widget _buildBottomButtonGroup() {
        var widgets = <Widget>[];
        if (negativeText != null && negativeText.isNotEmpty) widgets.add(_buildBottomCancelButton());
        if (positiveText != null && positiveText.isNotEmpty) widgets.add(_buildBottomPositiveButton());
        return new Flex(
          direction: Axis.horizontal,
          children: widgets,
        );
      }
    
      Widget _buildBottomCancelButton() {
        return new Flexible(
          fit: FlexFit.tight,
          child: new FlatButton(
            onPressed: onCloseEvent,
            child: new Text(
              negativeText,
              style: TextStyle(
                fontSize: 16.0,
              ),
            ),
          ),
        );
      }
    
      Widget _buildBottomPositiveButton() {
        return new Flexible(
          fit: FlexFit.tight,
          child: new FlatButton(
            onPressed: onPositivePressEvent,
            child: new Text(
              positiveText,
              style: TextStyle(
                color: Color(Colors.teal.value),
                fontSize: 16.0,
              ),
            ),
          ),
        );
      }
    } 
    
    

    上面的自定义dialog就是继承原生Dialog之后结合其他控件使用的一种典型例子,为了满足需求你还可以加个回调函数final Function callback; 修改之后的回掉函数,增加dialog操作之后回调给页面。具体的一步步操作就好了。

    2,下面介绍第二种,纯手工制作的控件(自绘)

    我们就来个简单的例子。
    最近看了别人博客跟着做了个小球下落的功能,那就看个自定义小球的例子吧

    import 'dart:ui';
    
    import 'package:flutter/material.dart';
    
    ///小球信息描述类
    class Ball {
      double aX; //加速度
      double aY; //加速度Y
      double vX; //速度X
      double vY; //速度Y
      double x; //点位X
      double y; //点位Y
      Color color; //颜色
      double r;//小球半径
    
      Ball({this.x=0, this.y=0, this.color, this.r=10,
        this.aX=0, this.aY=0, this.vX=0, this.vY=0});
    }
    
    ///画板Painter
    class RunBallView extends CustomPainter {
      Ball _ball; //小球
      Rect _area;//运动区域
      Paint mPaint; //主画笔
      Paint bgPaint; //背景画笔
    
      RunBallView(this._ball,this._area) {
        mPaint = new Paint();
        bgPaint = new Paint()..color = Color.fromARGB(148, 198, 246, 248);
      }
    
      @override
      void paint(Canvas canvas, Size size) {
        canvas.drawRect(_area, bgPaint);
        _drawBall(canvas, _ball);
      }
    
      @override
      bool shouldRepaint(CustomPainter oldDelegate) {
        return true;
      }
    
      ///使用[canvas] 绘制某个[ball]
      void _drawBall(Canvas canvas, Ball ball) {
        canvas.drawCircle(
            Offset(ball.x, ball.y), ball.r, mPaint..color = ball.color);
      }
    }
    
    var _area= Rect.fromLTRB(0+40.0,0+200.0,280+40.0,200+200.0);
    var _ball = Ball(color: Colors.blueAccent, r: 10,x: 40.0+140,y:200.0+100);
     
    var child = Scaffold(
      body: CustomPaint(
        painter: RunBallView(_ball,_area),
      ),
    );
    

    这个自身根据需要作出自定义的小球,然后再加上算法和函数就可以随心地做你想要的东西了。

    这一篇章写得比较粗糙,本来打算做一个自定义的下雪动画的,下次再上代码介绍吧,先理解好先。
    也可以参考下面文章理解:
    https://book.flutterchina.club/chapter10/intro.html

    相关文章

      网友评论

          本文标题:Flutter开发之自定义view,widget

          本文链接:https://www.haomeiwen.com/subject/wfhmxhtx.html