Flutter学习之旅(二)----MD风格和点击事件

Flutter中有许多常用的控件,比如下面的:
Text:文本控件,相当于安卓TextView;
Row,Column:相当于安卓LinearLayout的两个方向;
Stack:与Positioned控件配合,放到top, right, bottom, or left;
Container:矩形控件,可与BoxDecoration配合来装饰 background, a border, or a shadow,可用margins, padding, and constraints来设置其尺寸。
当然还有很多其他的控件,后面用到的时候再一一介绍,这里大家先有个印象。

下面是一个常见页面的简单布局的完整代码:

import 'package:flutter/material.dart';
class MyAppBar extends StatelessWidget{
  MyAppBar({this.title});
  final Widget title;
  @override
  Widget build(BuildContext context) {
    return new Container(//矩形控件
      height: 50.0,//顶部导航栏的高度
      padding: const EdgeInsets.symmetric(horizontal: 10.0),//顶部导航栏与两侧的距离,horizontal表示水平方向
      decoration: new BoxDecoration(color: Colors.blue[500]),//顶部导航栏颜色
      child: new Row(//Row相当于LinearLayout水平布局,包括菜单按钮,标题,搜索按钮
        children: [new IconButton(icon:new Icon( Icons.menu), onPressed: null),//左上角菜单按钮,系统提供了图片,无点击事件
        new Expanded(child: title),//标题文本充满整行布局
        new IconButton(icon: new Icon(Icons.search), onPressed: null),],//右上角搜索按钮,系统提供了图片,无点击事件
      ), );
  }
}

class MyScalffold extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return new Material(
      child: new Column(//Column相当于LinearLayout垂直布局,包括顶部标题栏和下面的内容
        children: [
          new MyAppBar(title: new Text("我是标题",style: Theme.of(context).primaryTextTheme.title,),
          ),new Expanded(child: new Center(child: new Text('内容:Hello wrold'),),),
        ],
      ),
    );
  }
  }

  void main(){//主函数入口
  runApp(new MaterialApp(title: 'My app',home: new MyScalffold(),));
  }

运行结果
Flutter学习之旅(二)----MD风格和点击事件_第1张图片

上面代码同样界面的MD(Material Design)风格

import 'package:flutter/material.dart';
void main(){
  runApp(new MaterialApp(title: 'Flutter Tutorial',home: new TutorialHome(),));
}
class TutorialHome extends  StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return new Scaffold(//替换上面代码中的MyScaffold
      appBar: new AppBar(//替换上面代码中的MyAppBar
        leading: new IconButton(
            icon: new Icon(Icons.menu), tooltip: 'ddd', onPressed: null,),
        title: new Text('MD风格'),
        actions: [new IconButton(icon: new Icon(Icons.search), onPressed: null)],
      ),
      body: new Center(child: new Text('Hello World'),),
      floatingActionButton: new FloatingActionButton(tooltip: '增加',child: new Icon(Icons.add), onPressed: null),
    );
  }
}

运行结果
Flutter学习之旅(二)----MD风格和点击事件_第2张图片
我们将上个工程中自定义的MyAppBar和MyScaffold 切换为系统AppBar和 Scaffold,我们就使用了MD风格,比如说顶部导航栏有阴影效果等等,同时代码是不是简洁了许多?。值得注意的是,我们将AppBar控件作为参数,传递给另外一个控件Scaffold,将leading控件, actions 控件和title控件作为AppBar控件的参数 ,这一点贯穿整个框架。

–手势控制
点击Container控件,GestureDetector控件将调用onTap()方法,然后打印信息。GestureDetector支持的手势包括taps, drags和 scales,许多控件,比如 IconButton, RaisedButton和 FloatingActionButton控件被点击后会调用onPressed()方法。

import 'package:flutter/material.dart';
void main(){
  runApp(new MaterialApp(title: '手势Demo',home: new MyButton(),));
}
class MyButton extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      onTap: (){print('BUtton was tapped');},
      child: new Container(//Container:矩形控件,可与BoxDecoration配合来装饰 background, a border, or a shadow,
        // 可用margins, padding, and constraints来设置其尺寸。
        height: 30.0,
        padding: const EdgeInsets.all(8.0),
        margin: const EdgeInsets.symmetric(horizontal: 8.0),
        decoration: new BoxDecoration(borderRadius: new BorderRadius.circular(5.0),//背景的圆角
          color: Colors.lightGreen[500],),//背景色
        child: new Center(child: new Text('Engage'),),//显示 "Engage"
      ),);}
}

运行结果
Flutter学习之旅(二)----MD风格和点击事件_第3张图片

–为了响应输入而改变控件
前面我们都是用的无状态的控件,这些无状态的控件从它们的父控件接受参数。为了满足更复杂的场景,APP需要记住一些状态,即Flutter中的StateFullWidgets控件。它知道如何产生用来保持状态的State对象,

import 'package:flutter/material.dart';
void main() {
  runApp(new Counter());
}
class Counter extends StatefulWidget{
  @override
  _CounterState createState() => new _CounterState();
}
class _CounterState extends State<Counter>{
  int _counter=0;
  void _increment(){
    setState((){_counter++;});
  }
  @override
  Widget build(BuildContext context) {
    return new Row(children: [new FloatingActionButton(onPressed: _increment,
      //不使用FloatingActionButton,使用RaisedButton会报错
      child: new Text('增加'),),
    new Text('Count = $_counter')],);// $_counter表示获取_counter的值
  }
}

运行结果
Flutter学习之旅(二)----MD风格和点击事件_第4张图片

过程中遇到的错误
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following assertion was thrown building MaterialButton(dirty; state:
_MaterialButtonState#767c2()):
No Material widget found.
MaterialButton widgets require a Material widget ancestor.

刚开始使用RaisedButton时报错了,我以为是因为使用了如下的运行方式,以为Counter()不是继承自MD风格的控件
runApp(new MaterialApp(title: ‘Flutter Tutorial’, home: new Counter(), ));
于是我将其修改为
runApp(new Counter());
问题依旧,怎么办,继续排查,值得怀疑的地方是最后面bulid方法里面返回的内容,
return new Row(children: [new RaisedButton(onPressed: _increment,
child: new Text(‘增加’),), new Text(‘Count = $_counter’)],);
不知道是不是这里问题,不管,先试试,返回最简单的 return new Center(child: new Text(‘Hello Flutter!’),运行正常。果然是这里,尝试用new Center替换new Row,FloatingActionButton替换RaisedButton,最终找到问题。

这篇文章主要介绍一些常见控件的用法等基础知识,代码写了注释,都是我个人的理解,可能有些地方表达不准确,理解不够深,这也正是我学习的目的意义。

由于工程大部分地方都相同,只有main.dart文件内容不同,只提供demo2和demo4的源码,也就是MD风格和最后的点击事件。其余的自己复制文章中的代码,然后替换掉main.dart里面的代码即可。
源码下载

你可能感兴趣的:(Flutter开发,Flutter学习之旅)