flutter 如何使用浮动操作按钮导航到新屏幕

b4wnujal  于 2023-10-22  发布在  Flutter
关注(0)|答案(3)|浏览(135)

我试图从我的主页移动到另一个屏幕使用浮动操作按钮,但不幸的是,浮动操作按钮不工作。点击按钮后,下一个屏幕没有出现,控制台显示上下文问题,但我无法绕过它。

import 'package:flutter/material.dart';
import 'package:kitchen/Screen/kitchenscreen.dart';
import 'package:kitchen/Screen/FoodScreen.dart';

void main ()
{
  runApp(myapp());
}

class myapp extends StatelessWidget
{

  @override
  Widget build(BuildContext context)
  {
    return MaterialApp(
      home:Scaffold
        (
        backgroundColor:Colors.white60,
        appBar: AppBar(
        backgroundColor: Colors.green,
        title: const Text('Teach'),
        actions: [
          IconButton(onPressed:(){},
             icon: const Icon(Icons.favorite),)
        ] ,
      ),
      body:const  Center(
        child: Text('Add Content here'),
      ),
        floatingActionButton: FloatingActionButton(
          onPressed: (){Navigator.push(context,
              MaterialPageRoute(builder: (context)=>FoodScreen()),);},
          backgroundColor:Colors.green,
          child:const  Icon(Icons.add),
        ),
      )
    );
  }
}
import 'package:flutter/material.dart';

class FoodScreen extends StatelessWidget{
  const FoodScreen({Key ? key}) :super(key:key);

  Widget build(BuildContext context)
  {
    return const Scaffold(
        body:Center(child:Text('hello')));
  }
}

我试图在点击浮动操作按钮后获得一个屏幕,但不幸的是点击屏幕后没有出现。

utugiqy6

utugiqy61#

在您的代码中,您在FloatingActionButtononPressed函数中使用的上下文可能与Navigator没有关联,导航可能无法按预期工作,因此您必须使用navigatorKeyBuilder小部件提供适当的context
您可以像这样使用Builder小部件:

...
floatingActionButton: Builder(
  builder: (context) => FloatingActionButton(
    onPressed: () {
      Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => FoodScreen()),
      );
    },
    backgroundColor: Colors.green,
    child: const Icon(Icons.add),
  ),
),
...
xtfmy6hx

xtfmy6hx2#

因为传递给Navigator.pushcontext是错误的。它是myapp的上下文,而不是停留在Scaffold小部件中。
如果你想使用Navigator,那么你必须传递context,它留在Scaffold中。尝试Buildercontext留在Scaffold内:

Builder(
        builder: (builderContext) => FloatingActionButton(
          onPressed: () {
            Navigator.push(
              builderContext,
              MaterialPageRoute(builder: (builderContext) => FoodScreen()),
            );
          },
          backgroundColor: Colors.green,
          child: const Icon(Icons.add),
        ),
      )
mfpqipee

mfpqipee3#

有两种不同的方法来解决您的问题,让我们逐一讨论。
1.第一个方法是可选参数,这意味着你不能给予上下文,你只是把_作为可选参数。

Navigator.push(
        context,
        MaterialPageRoute(builder: (_) => FoodScreen()),
      );
  • 另一个是最好的选择,这是上下文自由导航,我个人使用这个,因为在某些时候,你需要访问上下文,但上下文是不可用的。我会告诉你正确的方法,以及如何在你的程序中一步一步地实现。
  • 首先,让我们创建一个文件,并设置我们的上下文自由导航文件下面是代码。
    navigator_service.dart
import 'package:flutter/material.dart';

class NavigationService {
  NavigationService._internal();
  static final NavigationService instance = NavigationService._internal();

  late final NavigatorState currentState = navigationKey.currentState!;

  final GlobalKey<NavigatorState> navigationKey = GlobalKey<NavigatorState>();

  dynamic goBack([dynamic popValue]) {
    return navigationKey.currentState!.pop(popValue);
  }

  BuildContext get context => currentState.context;

  void navigateToScreen(String page, {dynamic arguments}) =>
      navigationKey.currentState?.pushNamed(page, arguments: arguments);

  Future<void> replaceScreen(Widget page, {dynamic arguments}) async =>
      navigationKey.currentState!.pushReplacement(
        MaterialPageRoute(
          builder: (_) => page,
        ),
      );

  void popToFirst() =>
      navigationKey.currentState!.popUntil((route) => route.isFirst);
}
  • 现在在上面的文件中,我们定义了所有的push,pop和replace screen的方法。现在你的工作很容易,每当你想导航到另一个屏幕,只需替换你的代码。
NavigationService.instance.navigateToScreen(Your Route Name),

但你需要为此创建路由生成器,工作将很容易。

route_generator.dart

// ignore_for_file: cast_nullable_to_non_nullable

import 'package:flutter/material.dart';
import 'package:tmdb_movie_app/routes/routes.dart';

class RouteGenerator {
  static Route<dynamic> generateRoute(RouteSettings settings) {
    final args = settings.arguments;

    switch (settings.name) {
      case '/':
        return MaterialPageRoute(
          builder: (_) => const SelectPages(),
        );
      case '/Your Route':
        return MaterialPageRoute(
          builder: (_) => const HomePage(),
        );
      
      default:
        return errorRoute();
    }
  }

  static Route<dynamic> errorRoute() {
    return MaterialPageRoute(
      builder: (context) {
        return Scaffold(
          appBar: AppBar(
            centerTitle: true,
            title: Text(
              'Error',
              style: Theme.of(context).textTheme.titleLarge,
            ),
          ),
          body: const Center(
            child: Text('No Routes Found'),
          ),
        );
      },
    );
  }
}

相关问题