onPressed: () async {
// Navigator.push 會回傳一個 Future,如果你對這里使用的 await不太熟悉,可以參考
// https://www.dartlang.org/guides/language/language-tour#asynchrony-support
var msg = await Navigator.push(
context,
MaterialPageRoute(builder: (_) => SecondScreen())
);
debugPrint(‘msg = $msg’);}
我們還可以在 MaterialApp 里設定好每個 route 對應的頁面,然后使用 Navigator.pushNamed(context, routeName) 來打開它們:
MaterialApp(
// 從名字叫做 ‘/’ 的 route 開始(也就是 home)
initialRoute: ‘/’,
routes: {
‘/’: (context) => HomeScreen(),
‘/about’: (context) => AboutScreen(),
},
);
接下來,我們通過實作一個 echo 客戶端的前端頁面來綜合運用前面所學的知識(邏輯部分我們留到下一篇文章再補充),
echo 客戶端
訊息輸入頁
這一節我們來實作一個用戶輸入的頁面,UI 很簡單,就是一個文本框和一個按鈕,


這里的按鈕本應該使用 RaisedButton 或 FlatButton,為了演示如何監聽手勢事件,我們這里故意自己用 Container 做了一個按鈕,然后通過 InkWell 監聽手勢事件,InkWell 除了上面展示的幾個事件外,還帶有一個水波紋效果,如果不需要這個水波紋效果,讀者也可以使用 GestureDetector,
訊息串列頁面
我們的 echo 客戶端共有兩個頁面,一個用于展示所有的訊息,另一個頁面用戶輸入訊息,后者在上一小節我們已經寫好了,下面,我們來實作用于展示訊息的頁面,
頁面間跳轉
我們的頁面包含一個串列和一個按鈕,串列用于展示資訊,按鈕則用來打開上一節我們所實作的 AddMessageScreen,這里我們先添加一個按鈕并實作頁面間的跳轉,
// 這是我們的訊息展示頁面class MessageListScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(‘Echo client’),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// push 一個新的 route 到 Navigator 管理的堆疊中,以此來打開一個頁面
Navigator.push(
context,
MaterialPageRoute(builder: (_) => AddMessageScreen())
);
},
tooltip: ‘Add message’,
child: Icon(Icons.add),
)
);
}
}
在訊息的輸入頁面,我們點擊 Send 按鈕后就回傳:
onTap: () {
debugPrint(‘send: ${editController.text}’);
Navigator.pop(context);
}
最后,我們加入一些骨架代碼,實作一個完整的應用:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: ‘Flutter UX demo’,
home: MessageListScreen(),
);
}
}
但是,上面代碼所提供的功能還不夠,我們需要從 AddMessageScreen 中回傳一個訊息,
首先我們對資料建模:
class Message {
final String msg;
final int timestamp;
Message(this.msg, this.timestamp);
@override
String toString() {
return ‘Message{msg:
m
s
g
,
t
i
m
e
s
t
a
m
p
:
msg, timestamp:
msg, timestamp: timestamp}’;
}
}
下面是回傳資料和接收資料的代碼:
onTap: () {
debugPrint(‘send: ${editController.text}’);
final msg = Message(
editController.text,
DateTime.now().millisecondsSinceEpoch
);
Navigator.pop(context, msg);
},
floatingActionButton: FloatingActionButton(
onPressed: () async {
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (_) => AddMessageScreen())
);
debugPrint(‘result = $result’); }, // …)
把資料展示到 ListView

這段代碼里唯一的新知識就是給 MessageList 的 key 引數,我們下面先看看如何使用他,然后再說明它的作用:

引入一個 GlobalKey 的原因在于,MessageListScreen 需要把從 AddMessageScreen 回傳的資料放到 _MessageListState 中,而我們無法從 MessageList 拿到這個 state,
GlobalKey 的是應用全域唯一的 key,把這個 key 設定給 MessageList 后,我們就能夠通過這個 key 拿到對應的 statefulWidget 的 state,
現在,整體的效果是這個樣子的:

如果你遇到了麻煩,在 Github 上找到所有的代碼:
git clone https://github.com/Jekton/flutter_demo.git
cd flutter_demo
git checkout ux-basic
影片
Flutter 影片的核心是 Animation,Animation 接受一個時鐘信號(vsync),轉換為 T 值輸出,它控制著影片的進度和狀態,但不參與影像的繪制,最基本的 Animation 是 AnimationController,它輸出 [0, 1] 之間的值,
使用內置的 Widget 完成影片
為了使用影片,我們可以用 Flutter 提供的 AnimatedContainer、F
《Android學習筆記總結+最新移動架構視頻+大廠安卓面試真題+專案實戰原始碼講義》
【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整內容開源分享
adeTransition、ScaleTransition 和 RotationTransition 等 Widget 來完成,
下面我們就來演示如何使用 ScaleTransition:

AnimationController 的輸出是線性的,非線性的效果可以使用 CurveAnimation 來實作:

當然,我們還可以組合不同的影片:
class _AnimWidgetState extends State
with SingleTickerProviderStateMixin { // …
@override
Widget build(BuildContext context) {
var scaled = ScaleTransition(
child: FlutterLogo(size: 200.0),
scale: curve,
);
return FadeTransition(
child: scaled,
opacity: curve,
);
}
}
更多的影片控制元件,讀者可以參考 https://flutter.io/widgets/animation/,
自定義影片效果
上一節我們使用 Flutter 內置的 Widget 來實作影片,他們雖然能夠完成日常開發的大部分需求,但總有一些時候不太適用,這時我們就得自己實作影片效果了,
前面我們說,AnimationController 的輸出在 [0, 1] 之間,這往往對我們需要實作的影片效果不太方便,為了將數值從 [0, 1] 映射到目標空間,可以使用 Tween:
animationValue = Tween(begin: 0.0, end: 200.0).animate(controller) // 每一幀都會觸發 listener 回呼
…addListener(() {
// animationValue.value 隨著影片的進行不斷地變化,我們利用這個值來實作
// 影片效果
print(‘value = ${animationValue.value}’);
});
下面我們來畫一個小圓點,讓它往復不斷地在正弦曲線上運動,

先來實作小圓點沿著曲線運動的效果:


上面的影片中,我們只是對位置做出了改變,下面我們將在位置變化的同時,也讓小圓點從紅到藍進行顏色的變化,
class _AnimationState extends State
with SingleTickerProviderStateMixin {
// …
Animation color;
void _initState() {
// …
color = ColorTween(begin: Colors.red, end: Colors.blue).animate(controller);
controller.forward();
}
@override
Widget build(BuildContext context) {
// …
final color = this.color == null ? Colors.red : this.color.value;
return Container(
// 我們根據影片的進度設定圓點的位置
margin: EdgeInsets.only(left: marginLeft, top: marginTop),
// 畫一個小圓點
child: Container(
decoration: BoxDecoration(
color: color, borderRadius: BorderRadius.circular(7.5)),
width: 15.0,
height: 15.0,
),
);
}
}
在 GitHub 上,可以找到所有的代碼:
git clone https://github.com/Jekton/flutter_demo.git
cd flutter_demo
git checkout sin-curve
在這個例子中,我們還可以加多一些效果,比方說讓小圓點在運動的程序中大小也不斷變化、使用 CurveAnimation 改變它運動的速度,這些就留給讀者作為練習吧,
原創: 水晶蝦餃
原文鏈接:https://mp.weixin.qq.com/s/653zL1YvuMwysKu907EQ-g
原文轉自:[玉剛說]微信公眾號
阿里P7移動互聯網架構師進階視頻(每日更新中)免費學習請點擊:https://space.bilibili.com/474380680
checkout sin-curve
在這個例子中,我們還可以加多一些效果,比方說讓小圓點在運動的程序中大小也不斷變化、使用 CurveAnimation 改變它運動的速度,這些就留給讀者作為練習吧,
原創: 水晶蝦餃
原文鏈接:https://mp.weixin.qq.com/s/653zL1YvuMwysKu907EQ-g
原文轉自:[玉剛說]微信公眾號
阿里P7移動互聯網架構師進階視頻(每日更新中)免費學習請點擊:https://space.bilibili.com/474380680
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/377110.html
標籤:其他
上一篇:使用for回圈和函式創建字典
下一篇:Android單元測驗
