Flutter学习指南:交互、手势和动画(1),超硬核

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。

现在,整体的效果是这个样子的:

message-list

如果你遇到了麻烦,在 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、FadeTransition、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 随着动画的进行不断地变化。我们利用这个值来实现

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

最后

由于文章篇幅原因,我只把面试题列了出来,详细的答案,我整理成了一份PDF文档,这份文档还包括了还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 ,帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习。

容对你有帮助,可以添加下面V无偿领取!(备注Android)**
[外链图片转存中…(img-yyqQEm6w-1711395149592)]

最后

由于文章篇幅原因,我只把面试题列了出来,详细的答案,我整理成了一份PDF文档,这份文档还包括了还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 ,帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习。

需要的朋友可以私信我【答案】或者点击这里免费领取

  • 13
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值