獲取設(shè)備寬高
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
Android設(shè)置狀態(tài)欄透明
- 原生修改
public class MainActivity extends FlutterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
// api大于21設(shè)置狀態(tài)欄透明
getWindow().setStatusBarColor(0);
}
GeneratedPluginRegistrant.registerWith(this);
}
}
- flutter修改(么有測試過,自己測試下反正不難)
// 輸出渲染
void main() {
runApp(App());
if (Platform.isAndroid) {
// 以下兩行 設(shè)置android狀態(tài)欄為透明的沉浸。寫在組件渲染之后,是為了在渲染后進(jìn)行set賦值,覆蓋狀態(tài)欄,寫在渲染之前MaterialApp組件會覆蓋掉這個值。
SystemUiOverlayStyle systemUiOverlayStyle = SystemUiOverlayStyle(statusBarColor: Colors.transparent);
SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
}
}
區(qū)別final與const
在Dart中,當(dāng)你不需要去改變一個變量的時候,應(yīng)該使用final或者const,而不是使用var去聲明一個變量。一個final變量只允許被賦值一次,必須在定義時或者構(gòu)造函數(shù)參數(shù)表中將其初始化。
const所修飾的是編譯時常量,我們在編譯時就已經(jīng)知道了它的值,它的值是不可改變的。
const比final更加嚴(yán)格,看以下例子:
final List<String> list = [];
list.add('1'); // 正確
const List<String> list = [];
list.add('1'); // 錯誤,運行時報錯:Cannot add to an unmodifiable list
final timestamp = new DateTime.now().millisecondsSinceEpoch; // 正確
const timestamp = new DateTime.now().millisecondsSinceEpoch; // 錯誤,編譯前報錯:Const variables must be initialized with a constant value
FocusScope轉(zhuǎn)移焦點,隱藏輸入法

166723349530a968.gif
Container(
height: 500.0,
child: new GestureDetector(
onTap: () {
// 通過GestureDetector捕獲點擊事件,再通過FocusScope將焦點轉(zhuǎn)移至空焦點 new FocusNode()
FocusScope.of(context).requestFocus(FocusNode());
},
child: Container(
margin: EdgeInsets.all(30.0),
child: ListView(children: <Widget>[
TextField(
decoration: InputDecoration(labelText: 'Username'),
),
TextField(
decoration: InputDecoration(labelText: 'Password'),
)
])),
),
),
- 這里傳遞給FocusScope的context不能在MaterialApp下面,即你需要將這部分代碼放到獨立的一個Widget里面
定時任務(wù)
- 在我們的開發(fā)之中難免要用到定時,比如我們常用的獲取驗證碼的需求,下面請看利用定時器來實現(xiàn)這一功能需求
- 定義3個變量
int _seconds = 0;
String _verifyStr = "獲取驗證碼";
/// 定時器Timer
Timer _timer;
- 實現(xiàn)timer,代碼很清晰,簡單的說我設(shè)了10秒的倒計時,利用Timer.periodic方法來執(zhí)行,間隔時間是1秒
/// 倒計時
_startTimer() {
_seconds = 10;
_timer = Timer.periodic(new Duration(seconds: 1), (timer){
if(_seconds == 0){
_cancleTimer();
return;
}
_seconds--;
_verifyStr = "${_seconds}s";
if (_seconds == 0){
_verifyStr = "重新發(fā)送";
}
setState(() {});
});
}
_cancleTimer(){
_timer?.cancel();
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
/// 頁面銷毀的時候,清除timer
_cancleTimer();
}
- 執(zhí)行,并不是每次按都執(zhí)行_startTimer,加上判斷條件只有_seconds == 0時才執(zhí)行效果如下圖
new Container(
padding: const EdgeInsets.only(top: 15.0, left: 15.0),
child: new RaisedButton(
/// 觸發(fā)定時任務(wù)
onPressed: (_seconds == 0)?(){
_startTimer();
}:null,
child: new Text(_verifyStr),
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.all(new Radius.circular(15.0)),
),
textColor: Colors.blue,
color: Colors.yellowAccent,
disabledColor: Colors.yellowAccent,
disabledTextColor: Colors.blue,
),
),

GIF.gif
利用 Container的BoxDecoration裝飾實現(xiàn)漸變
- 例子如下
Container(
decoration: BoxDecoration(gradient: LinearGradient(
colors: [const Color(0xFFFFFFEE), const Color(0xFF999999),const Color(0xFF862547),],
tileMode: TileMode.repeated, // repeats the gradient over the canvas
),),
-
效果如下
漸變.png BoxDecoration的屬性
const BoxDecoration({
this.color, // 盒子顏色
this.image, // 圖片
this.border, 邊框顏色和線寬度
this.borderRadius, // 圓角度
this.boxShadow, // 陰影
this.gradient, // 漸變
this.backgroundBlendMode, // 混合Mode
this.shape = BoxShape.rectangle, // 形狀
})
- 邊框圓角實現(xiàn)
decoration: new BoxDecoration(
border: new Border.all(color: Color(0xFFFF0000), width: 1.0), // 邊色與邊寬度
color: Color(0xFF999999), // 盒子顏色
// borderRadius: new BorderRadius.circular((15.0)), // 圓角度
borderRadius: new BorderRadius.vertical(top: Radius.elliptical(20, 50)), // 也可控件一邊圓角大小
),
- Dart知識點(?. / ??)
- ?. 運算符在左邊為null的情況下會阻斷右邊的調(diào)用。
- ?? 運算符表示在左側(cè)表達(dá)式為null時為其設(shè)置默認(rèn)值。
對于表達(dá)式:
tar[a]?.tars(b)
如果tar為null或tar[a]為null或tars(b)的值為null,都會導(dǎo)致表達(dá)式為null。
-
operator重載操作符
operator 是 Dart 的一個關(guān)鍵字,它和運算符(如=,+,-)一起使用,表示一個 運算符重載函數(shù),在理解時可將operator和運算符(如operator=)視為一個函數(shù)名
關(guān)于混編中退出flutter頁面的時候黑屏的情況
if(Navigator.canPop(context)){
Navigator.pop(context, true);
}else {
SystemNavigator.pop();
}
關(guān)于ListView中嵌套使用ListView,請在子組件中設(shè)置以下屬性
shrinkWrap: true,
底部彈窗默認(rèn)點擊消失,如何保持面板點擊不消失
- 可以子組件外面包一層GestureDetector并設(shè)置onTap為false,攔截點擊事件可以使點擊底部面板區(qū)域時不消失。
showModalBottomSheet(
context: context,
builder: (context) {
return GestureDetector(
onTap: () => false,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
titleWidget,
twoWidget,
Expanded(
child: BottomUserRankingPage(
context,
lists: lists,
),
),
],
),
);
});
實現(xiàn)跳轉(zhuǎn)到廣告按back返回是主界面
Navigator.of(context).pushReplacementNamed('/Main');
Navigator.of(context).push(WebPage);
如何強制豎屏
void main() {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((_) {
runApp(new MyApp());
});
}
在線上的app,如果flutter報錯,那一片紅可是非常的辣眼睛,給用戶的體驗也很不好,其實我們可以自定義錯誤頁面
ErrorWidget.builder = (FlutterErrorDetails details) {
print(details.toString());
return Center(
child: Text("Sorry 我下班了"),
);
};
在Flutter中,加載本地圖片會存在一個加載過程。比如點擊圖標(biāo)做圖標(biāo)的切換時,那么首次會發(fā)生閃動的情況。尤其是做類似引導(dǎo)頁這類需求是,通過左右滑動切換圖片時會發(fā)生比較明顯的白屏一閃而過。
解決方法很簡單,就是使用 precacheImage,它將圖像預(yù)存到圖像緩存中。如果圖像稍后被使用,它會被加載得更快。
precacheImage(AssetImage("assets/mylogo"), context);
在iOS 13中遇到了http網(wǎng)頁打不開的問題,添加以下文字到Info.plist
yourdomain.com 是你請求的鏈接的域名
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>yourdomain.com</key>
<dict>
<key>NSExceptionAllowInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
