前言
種一棵樹最好的時間是十年前,其次是現在。
入門經驗
按理來說,從事web前端開發的學習react native更適合一些,可偏偏選擇了flutter,學起來只有掉頭髮的份
無奈沒有專案實戰,也只能忙裡偷閒的時候自己畫餅充飢。
本次成果最終樣子:
具體實現過程並不難,後面後直接貼程式碼。這裡主要總結一下學習到的開發技巧:
1. 圖片的使用
圖片資料夾如圖所示,按照官網的教程 使用圖片還需要在pubspec.yaml檔案中進行配置:
這是官網的使用方式,擔如果需要引入的圖片很多,那得多雞肋?所以查詢了一下資料,果然存在懶人方式:
如圖只需要配置一下檔案的路徑即可。
如何使用該圖片,需要在widget中配置圖片的路徑,如圖:
2. TextField
TextField widget需要被包裹在Scaffold widget中,否則會報錯textfield widgets require a material widget ancestor。
3. 鍵盤彈起報錯
當使用鍵盤輸入時,突然報錯A RenderFlex overflowed by 29 pixels on the bottom
解決辦法: 使用 SingleChildScrollView將原生包裹。
4. 左右佈局技巧
如圖需要一個居左對齊,一個需要居右對齊。這裡先取一個代號,忘記密碼:leftItem; 簡訊驗證碼登入:rightItem.這裡的實現方式是:
- 使用row包裹兩個leftItem和rightItem。這樣實現在一行顯示。
問題
圖中 **忘記密碼?**始終存在著一個padding無法去除,不解
程式碼:
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
void main() => 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) {
//設定適配尺寸 (填入設計稿中裝置的螢幕尺寸) 假如設計稿是按iPhone6的尺寸設計的(iPhone6 750*1334)
ScreenUtil.instance = ScreenUtil(width: 750, height: 1334)..init(context);
Widget buildTextField (name, placeHolder) {
return new Container(
height: ScreenUtil().setHeight(100),
child: new TextField(
decoration: InputDecoration(
contentPadding: EdgeInsets.all(ScreenUtil().setWidth(10)),
labelText: placeHolder,
prefixStyle: TextStyle(
letterSpacing: ScreenUtil().setWidth(10),
color: Color(0xFF333333)
),
prefixText: name
),
)
);
}
return new Scaffold(
body: new SingleChildScrollView(
child: new Container(
padding:new EdgeInsets.fromLTRB(ScreenUtil().setWidth(30), 0, ScreenUtil().setWidth(30), 0) ,
color: Color(0xFFFFFFFF),
child: new Column(
children: <Widget>[
new Container(
height: ScreenUtil().setHeight(510),
child: new Center(
child: new Image.asset(
'asset/images/logo_01.png',
width: ScreenUtil().setWidth(102),
height: ScreenUtil().setWidth(114),
),
)
),
buildTextField('賬號', '請輸入賬號'),
new Container(
margin: new EdgeInsets.only(top: ScreenUtil().setHeight(50)),
child: new Container(
height: ScreenUtil().setHeight(100),
child: new TextField(
decoration: InputDecoration(
contentPadding: EdgeInsets.all(ScreenUtil().setWidth(10)),
labelText: '請輸入密碼',
prefixStyle: TextStyle(
letterSpacing: ScreenUtil().setWidth(10),
color: Color(0xFF333333)
),
prefixText: '密碼',
suffixIcon: Icon(Icons.remove_red_eye)
),
)
)
),
new Container(
width: ScreenUtil().setWidth(690),
margin: EdgeInsets.only(top: ScreenUtil().setHeight(80)),
height: ScreenUtil().setHeight(70),
child: new RaisedButton(
onPressed: () {},
child: new Text(
'登入',
style: TextStyle(
color: Color(0xFFffffff)
)
),
color: Color(0xFF1b82d2)
),
),
new Container(
padding: EdgeInsets.only(top: ScreenUtil().setHeight(20), bottom: ScreenUtil().setHeight(20)),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new Expanded(
// child: new Text('忘記')
child: new Row(
children: <Widget>[
new FlatButton(
padding: EdgeInsets.zero,
onPressed: null, child: Text(
'忘記密碼?',
style: TextStyle(
color: Color(0xFF1b82d2)
),
)
),
new Expanded(child: new Text(''))
],
)
),
new FlatButton(
padding: EdgeInsets.zero,
onPressed: null, child: Text('簡訊驗證碼登入',
style: TextStyle(
color: Color(0xFF1b82d2)
),)
)
],
),
)
],
),
)
)
);
}
}
複製程式碼