stack嵌套 通常狀況下 stack是沒法嵌套,出現stack嵌套,佈局就會出亂 解決方式:就是第二個stack須要肯定寬高 appbar透明app
AppBar( backgroundColor: Colors.transparent, elevation: 0, }
container設置背景async
Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage('assets/icon_login_bg.png'), fit: BoxFit.cover, ), ), ),
背景圖在appBar之下ide
return new Scaffold( body: new Stack( children: <Widget>[ new Container( color: Colors.blue.shade200, ), new AppBar( title: new Text("App bar"), backgroundColor: Colors.transparent, elevation: 0.0, ), new Positioned( top: 80.0, left: 0.0, bottom: 0.0, right: 0.0, //here the body child: new Column( children: <Widget>[ new Expanded( child: Container( color: Colors.grey, ), ) ], ), ), ], ), );
登錄頁面佈局
import 'dart:async'; import 'package:flutte_xms/util/func_util.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class LoginPage extends StatefulWidget { @override _LoginPageState createState() => _LoginPageState(); } class _LoginPageState extends State<LoginPage> { static const defaultText = '點擊獲取驗證碼'; Timer countDownTimer; String vefifyCountText = defaultText; TextEditingController _mobileController; TextEditingController _verifyCodeController; Focus mobileFocus; @override Widget build(BuildContext context) { double screenWidth = FuntionUtil.screenwidth(context); double screenHeight = FuntionUtil.screenHeight(context); return Stack( children: <Widget>[ Container( alignment: Alignment.center, decoration: BoxDecoration( color: Colors.blue, image: DecorationImage( image: AssetImage('assets/icon_login_bg.png'), fit: BoxFit.cover, repeat: ImageRepeat.noRepeat, ), ), ), Scaffold( backgroundColor: Colors.transparent, appBar: AppBar( backgroundColor: Colors.transparent, elevation: 0, iconTheme: IconThemeData( color: Colors.white, ), ), body: GestureDetector( onTap: () { FocusScope.of(context).unfocus(); }, child: Container( height: screenHeight, width: screenWidth, alignment: FractionalOffset(0.5, 0.7), child: Padding( padding: EdgeInsets.zero, child: Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ Stack( alignment: FractionalOffset(0.5, 0.95), children: <Widget>[ Container( color: Colors.transparent, padding: EdgeInsets.only(top: 15, bottom: 30), child: Container( margin: EdgeInsets.only(left: 20, right: 20), // height: 200, child: Card( child: Column( children: <Widget>[ //請輸入手機號 Container( margin: EdgeInsets.only( top: 15, left: 12, right: 12), child: Row( children: <Widget>[ Container( height: 54, width: 30, alignment: Alignment.center, padding: EdgeInsets.only( left: 0, right: 5), child: Image.asset( 'assets/icon_login_verifycode.png'), ), Expanded( child: Container( margin: EdgeInsets.only(right: 14), height: 54, alignment: Alignment.center, child: Theme( data: Theme.of(context).copyWith( splashColor: Colors.transparent), child: TextField( controller: _mobileController, keyboardType: TextInputType.number, textInputAction: TextInputAction.next, cursorColor: Colors.orange, decoration: InputDecoration( hintText: '請輸入手機號', border: InputBorder.none, ), inputFormatters: [ LengthLimitingTextInputFormatter( 11) ], ), ), ), ), ], ), decoration: BoxDecoration( border: Border( bottom: BorderSide( width: 2, color: Colors.orange), ), ), ), //請輸入驗證碼 Padding( padding: EdgeInsets.only( top: 15, bottom: 80, left: 12, right: 12), child: Container( child: Row( children: <Widget>[ Container( height: 54, width: 30, alignment: Alignment.center, padding: EdgeInsets.only( left: 0, right: 5), child: Image.asset( 'assets/icon_login_verifycode.png'), ), Expanded( child: Container( margin: EdgeInsets.only(right: 14), height: 54, alignment: Alignment.center, child: Theme( data: Theme.of(context) .copyWith( splashColor: Colors.transparent), child: TextField( controller: _verifyCodeController, keyboardType: TextInputType.number, textInputAction: TextInputAction.done, cursorColor: Colors.orange, decoration: InputDecoration( hintText: '請輸入驗證碼', border: InputBorder.none, ), inputFormatters: [ LengthLimitingTextInputFormatter( 11) ], ), ), ), ), FlatButton( splashColor: Colors.transparent, highlightColor: Colors.transparent, // disabledColor: Colors.grey, disabledTextColor: Colors.grey[300], child: Text(vefifyCountText), onPressed: vefifyCountText != defaultText ? null : () { //開啓倒計時 _startTime(); }, ) ], ), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Colors.orange, width: 2), ), ), ), ), ], ), ), ), ), GestureDetector( child: FuntionUtil.button(context, '登錄'), onTap: () { FocusScope.of(context).unfocus(); }, ), ], ), Padding( padding: EdgeInsets.only(top: 10), child: Row( mainAxisSize: MainAxisSize.min, children: <Widget>[ Image.asset('assets/icon_login_agreed.png'), SizedBox( width: 5, ), Text('用戶贊成協議和隱私策略'), ], ), ), Padding( padding: EdgeInsets.only(top: 20), child: Text('本產品不對未成年人開放'), ) ], ), ), ), ), ), ], ); } //開啓定時器 void _startTime() { //置空 _cancelTime(); countDownTimer = Timer.periodic(Duration(seconds: 1), (t) { int second = 60 - t.tick; setState(() { //60-t.tick表明剩餘秒數,若是大於0,設置text爲剩餘秒數 if (second > 0) { vefifyCountText = '$second秒後從新獲取'; } else { vefifyCountText = '點擊獲取驗證碼'; _cancelTime(); } }); }); } //取消定時器 void _cancelTime() { countDownTimer?.cancel(); countDownTimer = null; } @override void dispose() { _cancelTime(); super.dispose(); } }