要监听用户 tap 事件,可以使用 GestureDetector
,也可以使用 InkWell
,InkWell
基本上也是 GestureDetector
,但是它能够触发涟漪效应。实现页面间导航使用 Navigator
类:
// category_item.dart
import 'package:flutter/material.dart';
import './category_meals_screen.dart';
class CategoryItem extends StatelessWidget {
final String title;
final Color color;
const CategoryItem(this.title, this.color);
// 响应 tap 事件,实现页面导航
void selectCategory(BuildContext ctx) {
// 对于 iOS,使用 CupertinoPageRoute
Navigator.of(ctx).push(MaterialPageRoute(
builder: (_) => CategoryMealsScreen(), // CategoryMealsScreen 目标页面
));
}
@override
Widget build(BuildContext context) {
return InkWell(
// 监听 tap 事件
onTap: () => selectCategory(context),
splashColor: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(15),
child: Container(
padding: const EdgeInsets.all(15),
child: Text(title, style: Theme.of(context).textTheme.headline6),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [color.withOpacity(0.7), color],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(15),
),
),
);
}
}
点击任意一个分类,导航到相应页面:
此页面对应 code:
// category_meals_screen.dart
import 'package:flutter/material.dart';
class CategoryMealsScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('The recipes')),
body: Center(child: Text('The Recipies For The Category')),
);
}
}
另一种实现导航的方式是将路由集中写到 main.dart 中,使用命名路由实现导航,这种code 更易于维护:
// main.dart
import 'package:flutter/material.dart';
import './category_meals_screen.dart';
import './categories_screen.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'DeliMeals',
theme: ThemeData(
primarySwatch: Colors.pink,
accentColor: Colors.amber,
canvasColor: Color.fromRGBO(255, 254, 229, 1),
fontFamily: 'Raleway',
textTheme: ThemeData.light().textTheme.copyWith(
bodyText1: TextStyle(
color: Color.fromRGBO(20, 51, 51, 1),
),
bodyText2: TextStyle(
color: Color.fromRGBO(20, 51, 51, 1),
),
headline6: TextStyle(
fontSize: 20,
fontFamily: 'RobotoCondensed',
fontWeight: FontWeight.bold,
),
),
),
home: CategoriesScreen(),
// 整个 App 的路由全部写到这里
routes: {
'/category-meals': (ctx) => CategoryMealsScreen(),
},
);
}
}
实现导航:
// category_item.dart
import 'package:flutter/material.dart';
class CategoryItem extends StatelessWidget {
final String id;
final String title;
final Color color;
const CategoryItem(this.id, this.title, this.color);
void selectCategory(BuildContext ctx) {
Navigator.of(ctx).pushNamed('/category-meals', arguments: {
'id': id,
'title': title,
});
}
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () => selectCategory(context),
splashColor: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(15),
child: Container(
padding: const EdgeInsets.all(15),
child: Text(title, style: Theme.of(context).textTheme.headline6),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [color.withOpacity(0.7), color],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(15),
),
),
);
}
}
目标页面:
// category_meals_screen.dart
import 'package:flutter/material.dart';
class CategoryMealsScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final routeArgs =
ModalRoute.of(context).settings.arguments as Map<String, String>;
print(routeArgs);
final categoryTitle = routeArgs['title'];
final categoryId = routeArgs['id'];
return Scaffold(
appBar: AppBar(title: Text(categoryTitle)),
body: Center(child: Text('The Recipies For The Category')),
);
}
}