Flutter:通过 NamedRoute 传递参数

问题描述 投票:0回答:1

我设法使用路由在页面之间移动来使一些代码正常工作。现在我正在尝试实现传递参数(将此作为我的参考:https://docs.flutter.dev/cookbook/navigation/navigate-with-arguments),但我收到以下错误,请问有人可以吗给我指明正确的方向吗?

非常感谢

代码:

void main() async {
   WidgetsFlutterBinding.ensureInitialized();
   await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);

  runApp(const Home());
}

class Home extends StatelessWidget {

  const Home({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),

      routes: {
        '/': (context) => ItemList(),
        '/factfile': (context) => ItemDetails(),
        ExtractArgumentsScreen.routeName: (context) => const ExtractArgumentsScreen(),
      },
    );
  }
}

class ItemList extends StatelessWidget {
  ItemList({Key? key}) : super(key: key) {
    _stream = _reference.snapshots();
  }

  CollectionReference _reference = FirebaseFirestore.instance.collection('example_table_name');

  late Stream<QuerySnapshot> _stream;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Item List'),
      ),
      body: StreamBuilder<QuerySnapshot>(
        stream: _stream,
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          //Check error
          if (snapshot.hasError) {
            return Center(child: Text('Some error occurred ${snapshot.error}'));
          }

          //Check if data arrived
          if (snapshot.hasData) {
            //get the data
            QuerySnapshot querySnapshot = snapshot.data;
            List<QueryDocumentSnapshot> documents = querySnapshot.docs;

            //Convert the documents to Maps
            List<Map> items = documents.map((e) =>
            {
              'name': e['name'],
              'dlastupd': e['dlastupd'],
              'dlastupd date': DateTime.fromMillisecondsSinceEpoch(e['dlastupd'] * 1000)
            }).toList();

            // sort in descending date order
            items.sort((a, b) => b["dlastupd"].compareTo(a["dlastupd"]));

            //Display the list
            return ListView.builder(

                itemCount: items.length,
                itemBuilder: (BuildContext context, int index) {
                  //Get the item at this index
                  Map thisItem = items[index];
                  //Return the widget for the list items
                  return ListTile(

                    title: Text(formatDate(thisItem['dlastupd date'], [dd, '', M]) + " - " + thisItem['name']),
                    onTap: () {
                      Navigator.pushNamed(
                        context,
                        '/factfile',
                        arguments: ScreenArguments(
                          'id': 'example_record_id_number',
                        ),
                      );
                    },
                  );
                });
          }

          //Show loader
          return Center(child: CircularProgressIndicator());
        },
      ), //Display a list // Add a FutureBuilder
    );
  }
}

class ItemDetails extends StatelessWidget {
  const ExtractArgumentsScreen({super.key});  // !!! This line causes an error !!!

  static const routeName = '/extractArguments';

  ItemDetails(this.itemId, {Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // Extract the arguments from the current ModalRoute
    // settings and cast them as ScreenArguments.
    final args = ModalRoute.of(context)!.settings.arguments as ScreenArguments;

    final DocumentReference docRef = FirebaseFirestore.instance.collection("example_table_name").doc(args.id);

    return Scaffold(
      appBar: AppBar(
        title: Text("Item Details"),
      ),
      body: FutureBuilder<DocumentSnapshot>(
        future: docRef.get(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Center(
              child: CircularProgressIndicator(),
            );
          } else if (snapshot.hasError) {
            return Center(
              // child: Text("Error: ${snapshot.error}"),
              child: Text("Oh no it's an error"),
            );
          } else {
            final data = snapshot.data!.data() as Map<String, dynamic>;
            return Center(
              child: Text(data["name"]),
            );
          }
        },
      ),
    );
  }
}

class ScreenArguments {
  final String id;

  ScreenArguments(this.id);
}

错误:

lib/main.dart:118:3: Error: Getters, setters and methods can't be declared to be 'const'.
Try removing the 'const' keyword.
  const ExtractArgumentsScreen({super.key});  // !!! This line causes an error !!!
  ^^^^^
lib/main.dart:117:7: Error: The non-abstract class 'ItemDetails' is missing implementations for these members:
 - ItemDetails.ExtractArgumentsScreen
Try to either
 - provide an implementation,
 - inherit an implementation from a superclass or mixin,
 - mark the class as abstract, or
 - provide a 'noSuchMethod' implementation.

class ItemDetails extends StatelessWidget {
      ^^^^^^^^^^^
lib/main.dart:118:9: Context: 'ItemDetails.ExtractArgumentsScreen' is defined here.
  const ExtractArgumentsScreen({super.key});  // !!! This line causes an error !!!
        ^^^^^^^^^^^^^^^^^^^^^^
lib/main.dart:38:46: Error: Too few positional arguments: 1 required, 0 given.
        '/factfile': (context) => ItemDetails(),
                                             ^
lib/main.dart:123:3: Context: Found this candidate, but the arguments don't match.
  ItemDetails(this.itemId, {Key? key}) : super(key: key);
  ^^^^^^^^^^^
lib/main.dart:39:62: Error: Couldn't find constructor 'ExtractArgumentsScreen'.
        ExtractArgumentsScreen.routeName: (context) => const ExtractArgumentsScreen(),
                                                             ^^^^^^^^^^^^^^^^^^^^^^
lib/main.dart:39:9: Error: The getter 'ExtractArgumentsScreen' isn't defined for the class 'Home'.
 - 'Home' is from 'package:firestore_connection_test/main.dart' ('lib/main.dart').
Try correcting the name to the name of an existing getter, or defining a getter or field named 'ExtractArgumentsScreen'.
        ExtractArgumentsScreen.routeName: (context) => const ExtractArgumentsScreen(),
        ^^^^^^^^^^^^^^^^^^^^^^
lib/main.dart:101:27: Error: Expected an identifier, but got ''id''.
Try inserting an identifier before ''id''.
                          'id': 'example_record_id_number',
                          ^^^^
lib/main.dart:118:33: Error: Super-initializer formal parameters can only be used in generative constructors.
Try removing 'super.'.
  const ExtractArgumentsScreen({super.key});  // !!! This line causes an error !!!
                                ^^^^^
lib/main.dart:123:20: Error: 'itemId' isn't an instance field of this class.
  ItemDetails(this.itemId, {Key? key}) : super(key: key);
                   ^^^^^^

我确实尝试参考https://docs.flutter.dev/cookbook/navigation/navigate-with-arguments和我原来的帖子(没有NamedRoutes中的参数)Flutter:如何显示来自firebase的值获取查询?

flutter routes
1个回答
0
投票

你可以尝试一下我在我的项目中使用的这个方法

import 'package:flutter/material.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  runApp(const Home());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: first(),
      onGenerateRoute: Router.onRouteGenerator,
    );
  }
}

class Router {
  static MaterialPageRoute onRouteGenerator(settings) {
    switch (settings.name) {
      case second.routeName:
        return MaterialPageRoute(
          settings: settings,
          builder: (_) => second(
            title: settings.arguments as String,
          ),
        );

      default:
        return MaterialPageRoute(
          settings: settings,
          builder: (_) => const Material(
            child: Center(
              child: Text("404 page not founded"),
            ),
          ),
        );
    }
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: GestureDetector(
              onTap: () {
                Navigator.pushNamed(context, '/second', arguments: "test");
              },
              child: Container(
                height: 100,
                width: 100,
                color: Colors.grey,
              ))),
    );
  }
}

class second extends StatelessWidget {
  static const routeName = '/second';
  final String title;
  const second({Key? key, required this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: Container(
              height: 100, width: 100, color: Colors.grey, child: Text(title))),
    );
  }
}

© www.soinside.com 2019 - 2024. All rights reserved.