dart tabbarview不保持部件持久

kmb7vmvb  于 2023-10-13  发布在  其他
关注(0)|答案(1)|浏览(71)

我有一个个人资料页面,在中间,它有一个标签栏视图。标签栏视图具有3个标签以显示用户的数据。信息显示在屏幕的中下半部分。一个有生物标签,我想在点击按钮时进行编辑。一个新的屏幕出现输入数据和数据返回,以便生物小部件可以编辑新的文本。然而,当屏幕返回到个人资料页面时,生物文本确实会出现半秒钟,然后消失。我尝试了在stackoverflow中找到的解决方案,没有一个有效,除了一个说在文件的开头声明一个变量,所以它可以在任何地方访问。让变量等于输入的文本,然后显示出来。它工作,但我想知道为什么我的错误发生,所以我可以了解更多关于Flutter。谢谢
简档代码

class StudentProfile extends StatefulWidget {
  String id = "";

  StudentProfile(this.id);

  @override
  State<StudentProfile> createState() => _StudentProfileState();
}

class _StudentProfileState extends State<StudentProfile>
    with AutomaticKeepAliveClientMixin<StudentProfile> {
  @override
  Widget build(BuildContext context) {
    studentProfilecreation profile =
        locator.get<localData>().collectionOfstudents[0];
    MediaQueryData queryData;

    queryData = MediaQuery.of(context);
    //for tab bar in the middle to work.
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        backgroundColor: Colors.blue,
        body: Column(children: [
          //to position avatar pic and name, the two containers at top
          Stack(children: [
            Column(children: [
              Container(
                width: double.infinity,
                height: 100,
                decoration: BoxDecoration(color: Colors.blueGrey),
                child: SizedBox(
                    width: double.infinity,
                    height: 100,
                    child: Image.asset(
                        'assets/images/FINAL-FANTASY-VII-REMAKE_20200416212448-1024x576.jpg',
                        fit: BoxFit.fill)),
              ),
              Container(
                  width: double.infinity,
                  height: 125,
                  color: Color.fromARGB(255, 4, 25, 43)),
            ]),
            Positioned(
                top: queryData.size.width * 0.22,
                left: queryData.size.height * 0.02,
                child: SizedBox(
                    height: 125,
                    width: 125,
                    child: CircleAvatar(
                        radius: 0,
                        backgroundColor: const Color.fromARGB(122, 0, 0, 0),
                        child: CircleAvatar(
                          backgroundImage: AssetImage(
                            'assets/images/FINAL-FANTASY-VII-REMAKE_20200416212448-1024x576.jpg',
                          ),
                          radius: 60,
                        )))),
            Positioned(
                left: queryData.size.width * 0.40,
                top: queryData.size.height * 0.18,
                child: Text(profile.firstName + profile.lastName,
                    style: TextStyle(fontSize: 20, color: Colors.white)))
          ]),

          Container(
              //to place the bar inside of the container
              width: double.infinity,
              height: 50,
              decoration: BoxDecoration(
                  border: Border(
                      top: BorderSide(
                          color: Color.fromARGB(22, 255, 255, 255), width: 1))),
              child: AppBar(
                  //the tab names
                  backgroundColor: Colors.black,
                  bottom: TabBar(
                    tabs: const [
                      Tab(text: "Major"),
                      Tab(text: "Id number"),
                      Tab(text: "Classes and\nnotes"),
                      //  Tab(text: "Bio")
                    ],
                    isScrollable: true,
                  ))), //),
          Expanded(
              //will take rest of the screen space, for each tab, the function of that tab will return
              //with singlechildscrollview.
              child: TabBarView(children: [
            MajorInfo(),
            myid(),
            CoursesandNotes(),
            // MajorInfo(),
          ])),
        ]),
      ),
    );
  }

  @override
  // TODO: implement wantKeepAlive
  bool get wantKeepAlive => true;
}

生物方法代码

class MajorInfo extends StatefulWidget {
  MajorInfo({Key? key}) : super(key: key);
  String _major = "";

  @override
  State<MajorInfo> createState() => _Mymajorinfo();
}

class _Mymajorinfo extends State<MajorInfo>
    with AutomaticKeepAliveClientMixin<MajorInfo> {
  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Column(
      children: [
        ElevatedButton(
            onPressed: () => {
                  Navigator.push(
                      context,
                      MaterialPageRoute(
                          builder: (context) => Material(
                                child: TextField(
                                  onSubmitted: (value) {
                                    setState(() {
                                      widget._major = value;
                                      //_temp = value;
                                    });
                                    ;
                                    Navigator.pop(context);
                                  },
                                ),
                              )))
                },
            child: Text("Edit")),
        Text(widget._major)
      ],
    );
  }
}

忽略类的名称,它应该是mybio

ee7vknir

ee7vknir1#

在您的代码片段中,当按下“编辑”按钮时,它会打开一个新的路线,其中包含一个TextField,该TextField被 Package 在一个Material小部件中。
当用户在TextField中输入新值并提交它时,调用setState用新值更新widget._major。但是,这并不像预期的那样工作,因为_majorMajorInfo类的示例变量。
问题是,当您调用setState时,它只触发_Mymajorinfo小部件的重建,而不是MajorInfo小部件。因此,UI不会反映更新后的_major值,因为它仍然引用存储在MajorInfo小部件状态中的旧值,并且由于_major变量是MajorInfo小部件的属性,
你可以做的是,在build函数的级别上声明_major值,你可以通过添加调试器来检查这个重建,你会看到文本小部件用旧值重建。

相关问题