【问题标题】:How can I solve Flutter navigation BuilderContext subtype error?如何解决 Flutter 导航 BuilderContext 子类型错误?
【发布时间】:2020-12-07 19:28:02
【问题描述】:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter_auths/pages/searchservice.dart';
import 'package:flutter_auths/pages/tasks.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var queryResultSet = [];
  var tempSearchStore = [];

  initiateSearch(value) {
    if (value.length == 0) {
      setState(() {
        queryResultSet = [];
        tempSearchStore = [];
      });
    }

    var capitalizedValue =
        value.substring(0, 1).toUpperCase() + value.substring(1);

    if (queryResultSet.length == 0 && value.length == 1) {
      SearchService().searchByName(value).then((QuerySnapshot docs) {
        for (int i = 0; i < docs.documents.length; ++i) {
          queryResultSet.add(docs.documents[i].data);
        }
      });
    } else {
      tempSearchStore = [];
      queryResultSet.forEach((element) {
        if (element['Username'].startsWith(capitalizedValue)) {
          setState(() {
            tempSearchStore.add(element);
          });
        }
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: Text('Firestore search'),
        ),
        body: ListView(children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(10.0),
            child: TextField(
              onChanged: (val) {
                initiateSearch(val);
              },
              decoration: InputDecoration(
                  prefixIcon: IconButton(
                    color: Colors.black,
                    icon: Icon(Icons.arrow_back),
                    iconSize: 20.0,
                    onPressed: () {
                      Navigator.of(context).pop();
                    },
                  ),
                  contentPadding: EdgeInsets.only(left: 25.0),
                  hintText: 'Search by name',
                  border: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(4.0))),
            ),
          ),
          SizedBox(height: 10.0),
          GridView.count(
              padding: EdgeInsets.only(left: 10.0, right: 10.0),
              crossAxisCount: 2,
              crossAxisSpacing: 4.0,
              mainAxisSpacing: 4.0,
              primary: false,
              shrinkWrap: true,
              children: tempSearchStore.map((element) {
                return buildResultCard(element);
              }).toList())
        ]));
  }
}

Widget buildResultCard(data) {
  return Card(
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
      elevation: 2.0,
      child: Container(
          child: Column(
              children: <Widget> [ Text(data['Username'],
                textAlign: TextAlign.center,
                style: TextStyle(
                  color: Colors.black,
                  fontSize: 20.0,
                ),
              ),
                RaisedButton(
                  onPressed: () {
                    Navigator.push(
                      data,
                      MaterialPageRoute(builder: (data) => ProfilePage()),
                    );
                  },
                  child: const Text('asd', style: TextStyle(fontSize: 12)),
                ),
              ]
          )
      )
  );
}

在这里我从数据库中搜索一个用户,然后它在卡片中显示结果,我添加了一个按钮,通过单击它我想将页面导航到另一个页面,但出现以下错误。 this is the error and the app

所以我想点击特定用户的按钮并将页面重定向到该用户的个人资料。我该怎么做?

【问题讨论】:

    标签: flutter dart navigation flutter-navigation


    【解决方案1】:

    您收到此错误是因为您没有传递 buildContext,而是传递了数据。 因此,如果您从中更改代码,您的错误将被删除

    Navigator.push(
       data,
       MaterialPageRoute(builder: (data) => ProfilePage()),
    );
    

    Navigator.push(
       context,
       MaterialPageRoute(builder: (context) => ProfilePage(username: data['Username']))
    );
    

    这就是您应该将数据传递到个人资料页面的方式。

    还有

    Widget buildResultCard(data)
    

    改成

    Widget buildResultCard(context, data)
    

    buildResultCard(element);
    

    buildResultCard(context, element);
    

    【讨论】:

    • 它不工作。当我将数据更改为上下文时,它说它是未定义的。
    • 好吧,我将Widget buildResultCard(data) 更改为Widget buildResultCard(BuildContext context, data),但是这样我如何在GridView.count 中使用buildResultCard?第二个论点是什么?当我使用 return buildResultCard(context,element) 时它正在工作,但我收到错误:在小部件树中检测到 Duplicate GlobalKey。
    • 我已经更新了答案。如果您收到 Duplicate GlobalKey 错误,请尝试重新启动您的 IDE(Android Studio/VSCode/XCode)。如果还是报错,请参考stackoverflow.com/questions/49371221/…
    • 谢谢,它成功了。如何传递该用户的 uid 而不是其名称?
    【解决方案2】:

    首先,您需要导航到带有类似数据的页面

    Navigator.push(
       context,
       MaterialPageRoute(builder: (context) => ProfilePage(profileData: data))
    );
    

    那么您需要接收该数据

    class ProfilePage extends StatefulWidget {
      var profileData;
    
      ProfilePage({this.profileData});
    
      @override
      _ProfilePageState createState() => _ProfilePageState();
    }
    
    class _ProfilePageState extends State<ProfilePage> {
    
    
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Text(widget.profileData['username']),
          ),
        );
      }
    }
    

    您可以通过其他方式传递和接收数据

    Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => ProfilePage(),settings: RouteSettings(arguments: data))
    );
    

    然后

        class ProfilePage extends StatefulWidget {
    
      @override
      _ProfilePageState createState() => _ProfilePageState();
    }
    
    class _ProfilePageState extends State<ProfilePage> {
      var profileData;
      
      @override
      Widget build(BuildContext context) {
        profileData=ModalRoute.of(context).settings.arguments;
        return Scaffold(
          body: Center(
            child: Text(profileData['username']),
          ),
        );
      }
    }
    

    【讨论】:

    • 它不工作。当我将数据更改为上下文时,它说它是未定义的。
    • 好吧,我将Widget buildResultCard(data) 更改为Widget buildResultCard(BuildContext context, data),但是这样我如何在GridView.count 中使用buildResultCard?第二个论点是什么?当我使用 return buildResultCard(context,element) 时它正在工作,但我收到错误:在小部件树中检测到 Duplicate GlobalKey。
    猜你喜欢
    • 1970-01-01
    • 2019-04-26
    • 2020-11-28
    • 2020-08-19
    • 2019-03-19
    • 1970-01-01
    • 2016-01-25
    • 2021-11-14
    • 2021-03-23
    相关资源
    最近更新 更多