「这是我参加11月更文应战的第12天,活动详情检查:2021最终一次更文应战」
咱们现已完成了微信的发现界面的效果,可是此刻还有一个问题,cell
的点击事情如何处理,以及cell
点击时状况的改变,比方布景色等;这些问题在本篇文章中,咱们来逐个解说;
cell的点击事情
咱们的cell
是用Container
来构建的,可是Container
并不能支持手势操作,在Flutter
中,手势的操作经过GestureDetector
来完成。咱们将Container
用GestureDetector
包起来,这样咱们就可以界说点击事情了:
GestureDetector小常识
GestureDetector
是Flutter
中一个用于手势辨认的功能性组件,经过它,咱们可以辨认各种手势;在其内部封装了Listener
用来辨认语义化的手势;
咱们经过将Container
包括在GestureDetector
中来完成手势操作,常见的手势操作如下:
-
onTap
:点击; -
onTapDown
:按下; -
onTapCancel
:取消; -
onDoubleTap
:双击; -
onLongPress
:长安;
Navigator介绍
它是一个路由办理的组件,供给翻开
和退出
路由页的办法。Navigator
经过一个栈
来办理活动路由调集。一般当时屏幕显现的页面便是栈顶的路由。
最常用的两个办法为:
- Future push(Route route)
- 将给定的路由
入栈
,也便是翻开新的界面,回来值是一个Future
目标,用来接收新路由出栈
(封闭页面)时的回来数据;
- 将给定的路由
- bool pop([result])
- 将栈顶路由
出栈
,result
为页面封闭时回来给上一个页面的数据。
- 将栈顶路由
除此之外,Navigator
还有很多其他办法,如Navigator.replace
、Navigator.popUntil
等,咱们后续用到再解说;
cell点击跳转界面
cell
的点击事情现已完成了,怎样少得了进行push
操作呢?接下来咱们演示假如运用Navigator
进行push
操作;经过push
办法的界说,咱们知道需求给push
办法传递一个Route
,在咱们Flutter
中有一个MaterialPageRoute
这样一个现成的Route
,咱们此处运用它进行操作,其界说如下:
MaterialPageRoute({
required this.builder,
RouteSettings? settings,
this.maintainState = true,
bool fullscreenDialog = false,
})
-
builder
是一个WidgetBuilder
类型的回调函数,作用是构建路由页面的内容,回来值是一个Widget
。一般咱们完成此回调,用来回来路由的实例; -
settings
包括路由的装备信息,比方名称,是否初始路由(首页); -
maintainState
默认情况,当入栈一个新的路由时,本来的路由仍然会被保存在内存中,假如想要在路由没用的时分开释其所占用的所有资源,则可以设置maintainState
为false
; -
fullscreenDialog
表示新的路由页面是否是一个全屏的模态对话框。iOS
中,假如fullscreenDialog
为true
,新页面将会从屏幕底部滑入(而不是水平方向);
咱们比方给MaterialPageRoute
的结构办法传递一个builder
的参数,一般咱们的理解builder
是用来烘托的,其类型界说为:
typedef WidgetBuilder = Widget Function(BuildContext context);
简略来说,便是一个带BuildContext context
参数的办法,其回来值为Widget
,我便是说,咱们需求在builder
中界说一个回来新页面
(需求打来的界面)的办法,办法带参数BuildContext context
:
DetailPage
是咱们要进行push
翻开的新界面,在新界面中,咱们界说了其结构办法,传递一个title
,用来显现导航栏标题:
class DetailPage extends StatelessWidget {
final String? title;
DetailPage({this.title});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title ?? ''),
),
body: Center(
child: Text(title ?? ''),
),
);
}
}
效果如下:
有状况的cell
咱们留意到,在cell
点击的时分,微信的条目是会变灰然后恢复白色的,此刻很明显,微信的cell
是有状况的,那么咱们首要需求将咱们的cell
从StatelessWidget
改为StatefulWidget
;
改为有状况
的StatefulWidget
之后,咱们需求创立FoundCellState
承继自State
:
class _FoundCellState extends State<FoundCell> {
}
然后,将本来的build
办法,搬运到_FoundCellState
中来,搬运之后会发现,本来的特点不能直接访问了,此刻咱们需求运用widget.title
来访问title
特点:
此刻的
widget
指向咱们界说的StatefulWidget
,也便是FoundCell
;
此刻,咱们需求处理手势的三个状况:点击,点下去,取消;
return GestureDetector(
onTap: () {
print('1');
Navigator.of(context).push(
MaterialPageRoute(builder: (BuildContext context) {
return DetailPage(title: widget.title,);
})
);
},
onTapDown: (TapDownDetails details) {
print('2');
},
onTapCancel: () {
print('3');
},
);
咱们别离在这三个手势事情中打印数字,成果发现:
- 进行
push操作
,输出2 1
; - 点击拖动操作,输出
2 3
;
那么,也便是说,咱们需求在onTapDown
办法中,将cell
布景变灰色,onTap
和onTapCancel
两个办法中将cell
布景变白色:
效果如下:
需求留意的是,假如
cell
非常复杂,咱们把cell
整个改为有状况
的将会影响功能,在cell
比较复杂的情况下,咱们只需求将需求改变状况的那部分Widget
改为StatefulWidget
即可; 在将整个cell
都改为有状况
时,cell
也并非整体烘托;Widget
是界面的描绘
,并非真正的界面;从头构建时,构建的是描绘,而非界面自身;真正耗费功能的是其他东西,咱们后续再讲;