Flutter 正在使用的树通常建立
Column,
Rowand
Stackwidgets.
这些小部件采取了怎样指定规则构造函数参数
的儿童相对于父摆出来,你也可以影响
通过包裹它们成为个体儿童的布局
Expanded,
Flexible,
Positioned,
Align, or
Centerwidgets.
It is also possible to build complex layouts using
CustomMultiChildLayout. This is how
Scaffoldis
implemented internally, and an example of how to use it in an app appears in
the Shrine
demo.
You can also use
LayoutBuilderor
CustomPaint, or go down a layer and extend
RenderObjectas shown in the sector
example.
Doing your layouts manually like this is more work and creates more potential
for errors in corner cases, so I would try to get by with the high-level
layout primitives if you can.
To answer your specific questions:
- 使用
leading
和trailing
参数来AppBar
放置应用栏元素。如果要改用a Row,请使用mainAxisAlignment
ofMainAxisAlignment.spaceBetween
. - Use a
Row
with acrossAxisAlignment
ofCrossAxisAlignment.center
to position the fire icon and number underneath. - Use a
Column
with amainAxisAlignment
ofMainAxisAlignment.spaceBetween
to position your top and bottom title. (You should consider usingListTile
to lay out the list tiles, but you’ll lose control over the exact positioning if you do this.)
这是实现您提供的设计的代码段。在此示例中,我使用IntrinsicHeight来确定歌曲图块的高度,但是您可以通过将其硬编码为固定高度来提高性能。
import 'package:flutter/material.dart';void main() { runApp(new MyApp());}class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Flutter Demo', theme: new ThemeData( brightness: Brightness.dark, primaryColorBrightness: Brightness.dark, ), home: new HomeScreen(), debugShowCheckedModeBanner: false, ); }}class Song extends StatelessWidget { const Song({ this.title, this.author, this.likes }); final String title; final String author; final int likes; @override Widget build(BuildContext context) { TextTheme textTheme = Theme .of(context) .textTheme; return new Container( margin: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0), padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10.0), decoration: new BoxDecoration( color: Colors.grey.shade200.withOpacity(0.3), borderRadius: new BorderRadius.circular(5.0), ), child: new IntrinsicHeight( child: new Row( crossAxisAlignment: CrossAxisAlignment.stretch, children: <Widget>[ new Container( margin: const EdgeInsets.only(top: 4.0, bottom: 4.0, right: 10.0), child: new CircleAvatar( backgroundImage: new NetworkImage( 'http://thecatapi.com/api/images/get?format=src' '&size=small&type=jpg#${title.hashCode}' ), radius: 20.0, ), ), new Expanded( child: new Container( child: new Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ new Text(title, style: textTheme.subhead), new Text(author, style: textTheme.caption), ], ), ), ), new Container( margin: new EdgeInsets.symmetric(horizontal: 5.0), child: new InkWell( child: new Icon(Icons.play_arrow, size: 40.0), onTap: () { // TODO(implement) }, ), ), new Container( margin: new EdgeInsets.symmetric(horizontal: 5.0), child: new InkWell( child: new Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ new Icon(Icons.favorite, size: 25.0), new Text('${likes ?? ''}'), ], ), onTap: () { // TODO(implement) }, ), ), ], ), ), ); }}class Feed extends StatelessWidget { @override Widget build(BuildContext context) { return new ListView( children: [ new Song(title: 'Trapadelic lobo', author: 'lillobobeats', likes: 4), new Song(title: 'Different', author: 'younglowkey', likes: 23), new Song(title: 'Future', author: 'younglowkey', likes: 2), new Song(title: 'ASAP', author: 'tha_producer808', likes: 13), new Song(title: '


