解析开始
Flutter中一切皆widget,一切皆组件。学习Flutter中,必须首先了解Flutter的widget.先从最基本的MaterialApp和Scaffold开始了解
1 MaterialApp
一个封装了很多Android MD设计所必须要的组件的小部件,一般作为顶层widget使用。
继承关系
Inheritance
Object->Diagnosticable ->DiagnosticableTree ->Widget ->StatefulWidget ->MaterialApp
一般与以下widget一起使用
Scaffold: Material Design布局结构的基本实现。此类提供了用于显示drawer、snackbar和底部sheet的API。
Navigator,用于管理应用程序的页面堆栈。
MaterialPageRoute,它定义以特定于材料的方式转换的应用页面。
WidgetsApp,它定义基本的app元素但不依赖于材质库。
一般来说,在Flutter中,我们如果遵循MD设计时,顶层的Widget一般是MaterialApp,这里面我们可以指定主题样式,以便应用与APP整个页面中
2 Scaffold
Material Design布局结构的基本实现。此类提供了用于显示drawer、snackbar和底部sheet的API。
简单来说,Scanold就是一个提供MD设计中基本布局的widget,包括最上面的appBar,body,以及下部的drawer,snackbar等
import 'package:flutter/material.dart'; void main() { runApp(new MaterialApp( title: 'My app', // used by the OS task switcher home: new MyScaffold(), )); } class MyScaffold extends StatelessWidget { @override Widget build(BuildContext context) { // Material 是UI呈现的“一张纸” return new Material( // Column is 垂直方向的线性布局. child: new Column( children: <Widget>[ new MyAppBar( title: new Text( 'Example title', style: Theme.of(context).primaryTextTheme.title, ), ), new Expanded( child: new Center( child: new Text('Hello, world!'), ), ), ], ), ); } } class MyAppBar extends StatelessWidget { MyAppBar({this.title}); // Widget子类中的字段往往都会定义为"final" final Widget title; @override Widget build(BuildContext context) { return new Container( height: 56.0, // 单位是逻辑上的像素(并非真实的像素,类似于浏览器中的像素) padding: const EdgeInsets.symmetric(horizontal: 8.0), decoration: new BoxDecoration(color: Colors.blue[500]), // Row 是水平方向的线性布局(linear layout) child: new Row( //列表项的类型是 <Widget> children: <Widget>[ new IconButton( icon: new Icon(Icons.menu), tooltip: 'Navigation menu', onPressed: null, // null 会禁用 button ), // Expanded expands its child to fill the available space. new Expanded( child: title, ), new IconButton( icon: new Icon(Icons.search), tooltip: 'Search', onPressed: null, ), ], ), ); } }
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) { //Scaffold是Material中主要的布局组件. return new Scaffold( appBar: new AppBar( leading: new IconButton( icon: new Icon(Icons.menu), tooltip: 'Navigation menu', onPressed: null, ), title: new Text('Example title'), actions: <Widget>[ new IconButton( icon: new Icon(Icons.search), tooltip: 'Search', onPressed: null, ), ], ), //body占屏幕的大部分 body: new Center( child: new Text('Hello, world!'), ), floatingActionButton: new FloatingActionButton( tooltip: 'Add', // used by assistive technologies child: new Icon(Icons.add), onPressed: null, ), ); } }
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( appBar: new AppBar( title: new Text('应用'), ), body: new Center( child: new Text('Hello'), ), ); } }
import 'package:flutter/material.dart'; void main() { runApp(new MaterialApp( title: 'Flutter Tutorial', home: new MyApp(), )); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Flutter base UI Widget', home: new Scaffold( appBar: new AppBar( title: new Text('Flutter base UI Widget'), ), body: new ListView( children: <Widget>[ //add code new Text('Hello World', style: new TextStyle(fontSize: 32.0)), new Image.asset('images/lake.jpeg', 200.0,height: 200.0, fit: BoxFit.cover), new Icon(Icons.star, color: Colors.red[500]) ], ), ), ); } }
import 'package:flutter/material.dart'; void main() { runApp(new MaterialApp( title: 'Flutter Tutorial', home: new MyApp(), )); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { Widget titleSection = new Container( padding: const EdgeInsets.all(32.0), child: new Row( children: [ new Expanded( child: new Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ new Container( padding: const EdgeInsets.only(bottom: 8.0), child: new Text( 'Oeschinen Lake Campground', style: new TextStyle( fontWeight: FontWeight.bold, ), ), ), new Text( 'Kandersteg, Switzerland', style: new TextStyle( color: Colors.grey[500], ), ), ], ), ), new Icon( Icons.star, color: Colors.red[500], ), new Text('41'), ], ), ); return new MaterialApp( title: 'Flutter base UI Widget', home: new Scaffold( appBar: new AppBar( title: new Text('Flutter base UI Widget'), ), body: new ListView( children: <Widget>[ //add code titleSection ], ), ), ); } }
import 'package:flutter/material.dart'; void main() { runApp(new MaterialApp( title: 'Flutter Tutorial', home: new MyApp(), )); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Flutter Demo', theme: new ThemeData( primarySwatch: Colors.blue, ), home: new MyHomePage(title: 'GridView Demo'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => new _MyHomePageState(); } List<Container> _buildGridTileList(int count) { List<Container> containers = new List<Container>.generate( count, (int index) => new Container(child: new Image.asset('images/lake.jpeg', 100.0,height: 100.0, fit: BoxFit.cover))); return containers; } Widget buildGrid() { return new GridView.extent( maxCrossAxisExtent: 150.0, padding: const EdgeInsets.all(4.0), mainAxisSpacing: 4.0, crossAxisSpacing: 4.0, children: _buildGridTileList(30)); } class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text(widget.title), ), body: new Center( child: buildGrid(), ), ); } }
import 'package:flutter/rendering.dart' show debugPaintSizeEnabled; import 'package:flutter/material.dart'; void main() { // debugPaintSizeEnabled = true; runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { //关键代码 var card = new SizedBox( height: 210.0, //设置高度 child: new Card( elevation: 15.0, //设置阴影 shape: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(14.0))), //设置圆角 child: new Column( // card只能有一个widget,但这个widget内容可以包含其他的widget children: [ new ListTile( title: new Text('标题', style: new TextStyle(fontWeight: FontWeight.w500)), subtitle: new Text('子标题'), leading: new Icon( Icons.restaurant_menu, color: Colors.blue[500], ), ), new Divider(), new ListTile( title: new Text('内容一', style: new TextStyle(fontWeight: FontWeight.w500)), leading: new Icon( Icons.contact_phone, color: Colors.blue[500], ), ), new ListTile( title: new Text('内容二'), leading: new Icon( Icons.contact_mail, color: Colors.blue[500], ), ), ], ), ), ); return Scaffold( appBar: AppBar( title: Text(widget.title), elevation: 5.0, // tabbar的阴影 ), body: Center( child: card, ), ); } }