- 一个渐变色的背景—Container
Container(
child: Text(
"Hello World",
style: TextStyle(fontSize: 40.0, color: Colors.purple),
),
alignment: Alignment.topLeft,
width: 400.0,
height: 500.0,
// color: Colors.blueAccent,
// padding: const EdgeInsets.all(20),
padding: const EdgeInsets.fromLTRB(20, 50, 0, 0),
margin: const EdgeInsets.all(20),
// margin: const EdgeInsets.fromLTRB(20, 0, 0, 0),
// color: const Color(0xFF00FFFF),
decoration: BoxDecoration(
// color: Color.fromRGBO(0, 255, 255, 0.1)
gradient: LinearGradient(
colors: [
Colors.blueAccent,
Colors.purpleAccent,
Colors.amber,
],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
tileMode: TileMode.mirror,
stops: [0.1, 0.5, 0.8]),
// gradient: RadialGradient(colors: [Colors.blueAccent,Colors.amber,Colors.purple])
// gradient: SweepGradient(colors: [Colors.blueAccent,Colors.amber,Colors.purple],
// center: Alignment.centerLeft)
// border: Border.all(width: 2.0, color: Colors.red),
border: Border(
left: BorderSide(color: Colors.red, width: 3.0),
top: BorderSide(color: Colors.black, width: 3.0),
right: BorderSide(color: Colors.green, width: 3.0),
bottom: BorderSide(color: Colors.deepPurpleAccent, width: 5.0),
)),
),
2.自定义appbar
自定义一个可以左侧右侧抽屉菜单,以及平常返回按钮样式
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
const double kToolbarHeight =45;
const double _kLeadingWidth =
kToolbarHeight; // So the leading button is square.
// Bottom justify the kToolbarHeight child which may overflow the top.
class _ToolbarContainerLayout extends SingleChildLayoutDelegate {
const _ToolbarContainerLayout();
@override
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
return constraints.tighten(height: kToolbarHeight);
}
@override
Size getSize(BoxConstraints constraints) {
return Size(constraints.maxWidth, kToolbarHeight);
}
@override
Offset getPositionForChild(Size size, Size childSize) {
return Offset(0.0, size.height - childSize.height);
}
@override
bool shouldRelayout(_ToolbarContainerLayout oldDelegate) => false;
}
class MyAppBar extends StatefulWidget implements PreferredSizeWidget {
/// Creates a material design app bar.
///
/// The arguments [elevation], [primary], [toolbarOpacity], [bottomOpacity]
/// and [automaticallyImplyLeading] must not be null.
///
/// Typically used in the [Scaffold.appBar] property.
MyAppBar({
Key key,
this.leading,
this.automaticallyImplyLeading = true,
this.title,
this.actions,
this.flexibleSpace,
this.bottom,
this.elevation = 4.0,
this.backgroundColor,
this.brightness,
this.iconTheme,
this.textTheme,
this.primary = true,
this.centerTitle,
this.titleSpacing = NavigationToolbar.kMiddleSpacing,
this.toolbarOpacity = 1.0,
this.bottomOpacity = 1.0,
}) : assert(automaticallyImplyLeading != null),
assert(elevation != null),
assert(primary != null),
assert(titleSpacing != null),
assert(toolbarOpacity != null),
assert(bottomOpacity != null),
preferredSize = Size.fromHeight(
kToolbarHeight + (bottom?.preferredSize?.height ?? 0.0)),
super(key: key);
/// A widget to display before the [title].
///
/// If this is null and [automaticallyImplyLeading] is set to true, the
/// [AppBar] will imply an appropriate widget. For example, if the [AppBar] is
/// in a [Scaffold] that also has a [Drawer], the [Scaffold] will fill this
/// widget with an [IconButton] that opens the drawer (using [Icons.menu]). If
/// there's no [Drawer] and the parent [Navigator] can go back, the [AppBar]
/// will use a [BackButton] that calls [Navigator.maybePop].
final Widget leading;
/// Controls whether we should try to imply the leading widget if null.
///
/// If true and [leading] is null, automatically try to deduce what the leading
/// widget should be. If false and [leading] is null, leading space is given to [title].
/// If leading widget is not null, this parameter has no effect.
final bool automaticallyImplyLeading;
/// The primary widget displayed in the appbar.
///
/// Typically a [Text] widget containing a description of the current contents
/// of the app.
final Widget title;
/// Widgets to display after the [title] widget.
///
/// Typically these widgets are [IconButton]s representing common operations.
/// For less common operations, consider using a [PopupMenuButton] as the
/// last action.
///
/// ## Sample code
///
/// ```dart
/// Scaffold(
/// appBar: AppBar(
/// title: Text('Hello World'),
/// actions: <Widget>[
/// IconButton(
/// icon: Icon(Icons.shopping_cart),
/// tooltip: 'Open shopping cart',
/// onPressed: () {
/// // ...
/// },
/// ),
/// ],
/// ),
/// )
/// ```
final List<Widget> actions;
/// This widget is stacked behind the toolbar and the tabbar. It's height will
/// be the same as the app bar's overall height.
///
/// A flexible space isn't actually flexible unless the [AppBar]'s container
/// changes the [AppBar]'s size. A [SliverAppBar] in a [CustomScrollView]
/// changes the [AppBar]'s height when scrolled.
///
/// Typically a [FlexibleSpaceBar]. See [FlexibleSpaceBar] for details.
final Widget flexibleSpace;
/// This widget appears across the bottom of the app bar.
///
/// Typically a [TabBar]. Only widgets that implement [PreferredSizeWidget] can
/// be used at the bottom of an app bar.
///
/// See also:
///
/// * [PreferredSize], which can be used to give an arbitrary widget a preferred size.
final PreferredSizeWidget bottom;
/// The z-coordinate at which to place this app bar. This controls the size of
/// the shadow below the app bar.
///
/// Defaults to 4, the appropriate elevation for app bars.
final double elevation;
/// The color to use for the app bar's material. Typically this should be set
/// along with [brightness], [iconTheme], [textTheme].
///
/// Defaults to [ThemeData.primaryColor].
final Color backgroundColor;
/// The brightness of the app bar's material. Typically this is set along
/// with [backgroundColor], [iconTheme], [textTheme].
///
/// Defaults to [ThemeData.primaryColorBrightness].
final Brightness brightness;
/// The color, opacity, and size to use for app bar icons. Typically this
/// is set along with [backgroundColor], [brightness], [textTheme].
///
/// Defaults to [ThemeData.primaryIconTheme].
final IconThemeData iconTheme;
/// The typographic styles to use for text in the app bar. Typically this is
/// set along with [brightness] [backgroundColor], [iconTheme].
///
/// Defaults to [ThemeData.primaryTextTheme].
final TextTheme textTheme;
/// Whether this app bar is being displayed at the top of the screen.
///
/// If true, the appbar's toolbar elements and [bottom] widget will be
/// padded on top by the height of the system status bar. The layout
/// of the [flexibleSpace] is not affected by the [primary] property.
final bool primary;
/// Whether the title should be centered.
///
/// Defaults to being adapted to the current [TargetPlatform].
final bool centerTitle;
/// The spacing around [title] content on the horizontal axis. This spacing is
/// applied even if there is no [leading] content or [actions]. If you want
/// [title] to take all the space available, set this value to 0.0.
///
/// Defaults to [NavigationToolbar.kMiddleSpacing].
final double titleSpacing;
/// How opaque the toolbar part of the app bar is.
///
/// A value of 1.0 is fully opaque, and a value of 0.0 is fully transparent.
///
/// Typically, this value is not changed from its default value (1.0). It is
/// used by [SliverAppBar] to animate the opacity of the toolbar when the app
/// bar is scrolled.
final double toolbarOpacity;
/// How opaque the bottom part of the app bar is.
///
/// A value of 1.0 is fully opaque, and a value of 0.0 is fully transparent.
///
/// Typically, this value is not changed from its default value (1.0). It is
/// used by [SliverAppBar] to animate the opacity of the toolbar when the app
/// bar is scrolled.
final double bottomOpacity;
/// A size whose height is the sum of [kToolbarHeight] and the [bottom] widget's
/// preferred height.
///
/// [Scaffold] uses this this size to set its app bar's height.
@override
final Size preferredSize;
bool _getEffectiveCenterTitle(ThemeData themeData) {
if (centerTitle != null) return centerTitle;
assert(themeData.platform != null);
switch (themeData.platform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
return false;
case TargetPlatform.iOS:
return actions == null || actions.length < 2;
}
return null;
}
@override
_MyAppBarState createState() => _MyAppBarState();
}
class _MyAppBarState extends State<MyAppBar> {
void _handleDrawerButton() {
Scaffold.of(context).openDrawer();
}
void _handleDrawerButtonEnd() {
Scaffold.of(context).openEndDrawer();
}
@override
Widget build(BuildContext context) {
assert(!widget.primary || debugCheckHasMediaQuery(context));
assert(debugCheckHasMaterialLocalizations(context));
final ThemeData themeData = Theme.of(context);
final ScaffoldState scaffold = Scaffold.of(context, nullOk: true);
final ModalRoute<dynamic> parentRoute = ModalRoute.of(context);
final bool hasDrawer = scaffold?.hasDrawer ?? false;
final bool hasEndDrawer = scaffold?.hasEndDrawer ?? false;
final bool canPop = parentRoute?.canPop ?? false;
final bool useCloseButton =
parentRoute is PageRoute<dynamic> && parentRoute.fullscreenDialog;
IconThemeData appBarIconTheme =
widget.iconTheme ?? themeData.primaryIconTheme;
TextStyle centerStyle =
widget.textTheme?.title ?? themeData.primaryTextTheme.title;
TextStyle sideStyle =
widget.textTheme?.body1 ?? themeData.primaryTextTheme.body1;
if (widget.toolbarOpacity != 1.0) {
final double opacity =
const Interval(0.25, 1.0, curve: Curves.fastOutSlowIn)
.transform(widget.toolbarOpacity);
if (centerStyle?.color != null)
centerStyle =
centerStyle.copyWith(color: centerStyle.color.withOpacity(opacity));
if (sideStyle?.color != null)
sideStyle =
sideStyle.copyWith(color: sideStyle.color.withOpacity(opacity));
appBarIconTheme = appBarIconTheme.copyWith(
opacity: opacity * (appBarIconTheme.opacity ?? 1.0));
}
Widget leading = widget.leading;
//if (leading == null && widget.automaticallyImplyLeading) {
if (widget.automaticallyImplyLeading) {
if (hasDrawer) {
leading = IconButton(
//icon: const Icon(Icons.menu),
icon: leading ?? const Icon(Icons.menu),
onPressed: _handleDrawerButton,
tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
);
} else {
if (canPop)
leading = useCloseButton ? const CloseButton() : const BackButton();
}
}
if (leading != null) {
leading = ConstrainedBox(
constraints: const BoxConstraints.tightFor(width: _kLeadingWidth),
child: leading,
);
}
Widget title = widget.title;
if (title != null) {
bool namesRoute;
switch (defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
namesRoute = true;
break;
case TargetPlatform.iOS:
break;
}
title = DefaultTextStyle(
style: centerStyle,
softWrap: false,
overflow: TextOverflow.ellipsis,
child: Semantics(
namesRoute: namesRoute,
child: title,
header: true,
),
);
}
Widget actions;
if (widget.actions != null && widget.actions.isNotEmpty) {
actions = Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: widget.actions,
);
} else if (hasEndDrawer) {
actions = IconButton(
icon: const Icon(Icons.menu),
onPressed: _handleDrawerButtonEnd,
tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
);
}
final Widget toolbar = NavigationToolbar(
leading: leading,
middle: title,
trailing: actions,
centerMiddle: widget._getEffectiveCenterTitle(themeData),
middleSpacing: widget.titleSpacing,
);
// If the toolbar is allocated less than kToolbarHeight make it
// appear to scroll upwards within its shrinking container.
Widget appBar = ClipRect(
child: CustomSingleChildLayout(
delegate: const _ToolbarContainerLayout(),
child: IconTheme.merge(
data: appBarIconTheme,
child: DefaultTextStyle(
style: sideStyle,
child: toolbar,
),
),
),
);
if (widget.bottom != null) {
appBar = Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Flexible(
child: ConstrainedBox(
constraints: const BoxConstraints(maxHeight: kToolbarHeight),
child: appBar,
),
),
widget.bottomOpacity == 1.0
? widget.bottom
: Opacity(
opacity:
const Interval(0.25, 1.0, curve: Curves.fastOutSlowIn)
.transform(widget.bottomOpacity),
child: widget.bottom,
),
],
);
}
// The padding applies to the toolbar and tabbar, not the flexible space.
if (widget.primary) {
appBar = SafeArea(
top: true,
child: appBar,
);
}
appBar = Align(
alignment: Alignment.topCenter,
child: appBar,
);
if (widget.flexibleSpace != null) {
appBar = Stack(
fit: StackFit.passthrough,
children: <Widget>[
widget.flexibleSpace,
appBar,
],
);
}
final Brightness brightness =
widget.brightness ?? themeData.primaryColorBrightness;
final SystemUiOverlayStyle overlayStyle = brightness == Brightness.dark
? SystemUiOverlayStyle.light
: SystemUiOverlayStyle.dark;
return Semantics(
container: true,
explicitChildNodes: true,
child: AnnotatedRegion<SystemUiOverlayStyle>(
value: overlayStyle,
child: Material(
color: widget.backgroundColor ?? themeData.primaryColor,
elevation: widget.elevation,
child: appBar,
),
),
);
}
}
- 布局
Widget leftContent = new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text("7时20分",style: new TextStyle(fontSize: 20,fontWeight: FontWeight.w700,color: Colors.blue) ),
new Padding(padding: EdgeInsets.fromLTRB(0, 5, 0, 0)),
new Text('睡眠质量优秀',style: new TextStyle(fontSize: 13,fontWeight: FontWeight.w700,color: Colors.grey)),
new Padding(padding: EdgeInsets.fromLTRB(0, 5, 0, 0)),
new Text("你成功jibaile生物",style: new TextStyle(fontSize: 10,color: Colors.grey)),
],
);
return new Card(
color: Colors.white,
child:new Stack(
children: <Widget>[
new Padding(
padding: EdgeInsets.fromLTRB(20, 16, 20, 14),
child:new Row(
children: <Widget>[
new Expanded(child: leftContent),
new Stack(
children: <Widget>[
Positioned(
child: new SizedBox(
//限制进度条的高度
height: 60.0,
//限制进度条的宽度
width: 60,
child: new CircularProgressIndicator(
//0~1的浮点数,用来表示进度多少;如果 value 为 null 或空,则显示一个动画,否则显示一个定值
value: 0.3,
//背景颜色
backgroundColor: Colors.orange,
//进度条宽度
strokeWidth: 6,
//进度颜色
valueColor: new AlwaysStoppedAnimation<Color>(Colors.blue))),
),
Positioned(
left: 22,
top: 20,
child: new Image.asset("assets/images/home_moon.png", width: 20.0, height: 20.0,),
)
],
),
],
),
),]
),
);