在Flutter中如何导航到新屏幕?
这些问题相似,但问的比我多。
- Flutter - 导航到新屏幕并清除所有先前的屏幕
- Flutter:如何使用DropDownMenuItems导航到新屏幕
- Flutter:移动到新屏幕而不返回
- flutter 导航到新屏幕不起作用
下面我会添加一个答案。
在Flutter中如何导航到新屏幕?
这些问题相似,但问的比我多。
下面我会添加一个答案。
Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewScreen()));
其中 context
是小部件的 BuildContext,NewScreen
是第二个小部件布局的名称。
main.dart
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Home Screen')),
body: Center(
child: ElevatedButton(
child: const Text(
'Navigate to a new screen >>',
style: TextStyle(fontSize: 24.0),
),
onPressed: () {
_navigateToNextScreen(context);
},
),
),
);
}
void _navigateToNextScreen(BuildContext context) {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewScreen()));
}
}
class NewScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('New Screen')),
body: const Center(
child: Text(
'This is a new screen',
style: TextStyle(fontSize: 24.0),
),
),
);
}
}
使用Flutter预先制作的动画,可以使用它们各自的转换类来加载新屏幕。例如:
Container Transformation
基本上我们需要将第一个小部件或屏幕变形为下一个屏幕。为此,我们需要使用OpenContainer
。以下代码演示了ListView中的一个项目转换为其详细页。
@override
Widget build(BuildContext context) {
return Card(
color: Colors.white,
elevation: 2.0,
child: OpenContainer(
transitionType: ContainerTransitionType.fadeThrough,
closedColor: Theme.of(context).cardColor,
closedElevation: 0.0,
openElevation: 4.0,
transitionDuration: Duration(milliseconds: 1500),
openBuilder: (BuildContext context, VoidCallback _) => THENEXTSCREEN(),
closedBuilder: (BuildContext _, VoidCallback openContainer) {
return ListTile(
leading: Icon(Icons.album),
title: Text("ITEM NAME"),
);
},
),
);
}
共享轴
这个动效类似于标签页或步骤条,我们需要使用 SharedAxisTransition
、PageTransitionSwitcher
和一个状态来表示当前活动页面和上一个页面之间的转换。如果只是在两个页面之间切换,我们可以用一个简单的布尔值 isFirstPage
来实现。下面是使用 Provider 作为状态管理的代码片段:
@override
Widget build(BuildContext context) {
return Consumer<YourState>(
builder: (context, state, child) {
return PageTransitionSwitcher(
duration: const Duration(milliseconds: 1500),
reverse: !state.isFirstPage, // STATE
transitionBuilder: (
Widget child,
Animation<double> animation,
Animation<double> secondaryAnimation,
) {
return SharedAxisTransition(
child: child,
animation: animation,
secondaryAnimation: secondaryAnimation,
transitionType: SharedAxisTransitionType.horizontal,
);
},
child: state.isFirstPage? FIRSTPAGE() : SECONDPAGE(), // STATE
);
},
);
}
请注意,在所有这些场景中,我们不使用Navigator和MaterialPageRoute。所有这些代码都是从动画库中派生出来的,因此您可能希望先检查它。
使用Navigator.push()
通过后退导航到下一个屏幕
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),);
使用Navigator.pushReplacement()
跳转到下一个屏幕而不返回上一个屏幕。
Navigator.pushReplacement(
context,MaterialPageRoute(builder: (context) => SecondRoute()),);
这是一个完整的路由推送/弹出的示例:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Routes',
routes: {
'/login': (BuildContext context) => Login(),
// add another route here
// '/register': (BuildContext context) => Register(),
},
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Routes'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
onPressed: () {
// This gives the back button:
Navigator.of(context).pushNamed('/login');
// This doesn't give the back button (it replaces)
//Navigator.pushReplacementNamed(context, '/login');
},
child: Text('Login'),
),
],
),
),
);
}
}
class Login extends StatefulWidget {
@override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Login Page'),
),
body: Center(
child: RaisedButton(
onPressed: () {
// This will only work for pushNamed
Navigator.of(context).pop();
},
child: Text('Go back'),
),
));
}
}
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => NextScreenName()));
}
void main() {
setupLocator();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
routes: {
'/' : (BuildContext context)=>HomePage(),
'/register' : (BuildContext context)=>RegisterPage(),
},
);
}
}
您可以按照以下步骤从homepage.dart
页面向register.dart
页面添加按钮 onPressed
事件。
onPressed: (){
Navigator.pushReplacementNamed(context, '/register');
},
在形式化方法中:
Navigator.push(context, MaterialPageRoute(builder: (context)=>Second()));
在 GetX 方法中:
Get.to(Second());
Get.off(Third());
Get.offAll(Third());
Get.back();
FloatingActionButton(
onPressed: (){
Navigator.of(context).push(MaterialPageRoute(builder: (context) => const AddUser()));
},
child: const Icon(Icons.add),
),
onTap: () { Navigator.of(context).push(MaterialPageRoute( builder: (context) => NewScreen()));},
https://medium.com/@misterflutter/lesson-5-creating-new-screens-f740994190c7