为什么Navigator.pop()不刷新数据?

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

大家好,我正在尝试使用 flutter 构建一个应用程序,所以我有两个屏幕 HomeScreen() 和 RoutineScreen()。第一个是 Scaffold,主体中有一个子 Widget(一个名为 RoutinesWidget() 的 ListView),其中包含所有例程。第二个是创建一个例程。问题是,当我创建例程时,我使用一个按钮弹出到 HomeScreen() 但它不会刷新 ListView (我猜测这是因为当我使用 Navigator.pop() 时它会刷新 Scaffold但也许不是子 Widget?)

HomeScreen() 代码在这里:

import 'package:flutter/material.dart';
import 'package:workout_time/constants.dart';
import 'package:workout_time/Widgets/routines_widget.dart';
import 'package:workout_time/Widgets/statistics_widget.dart';
import 'package:workout_time/Screens/settings_screen.dart';
import 'package:workout_time/Screens/routine_screen.dart';

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  int _selectedIndex = 0;

  List<Widget> _views = [
    RoutinesWidget(),
    StatisticsWidget(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: kThirdColor,
      appBar: AppBar(
        leading: Icon(Icons.adb),
        title: Text("Workout Time"),
        actions: <Widget>[
          IconButton(
              icon: Icon(Icons.settings),
              onPressed: () => Navigator.push(context,
                  MaterialPageRoute(builder: (context) => SettingsScreen()))),
        ],
      ),
      body: _views[_selectedIndex],
      floatingActionButton: (_selectedIndex == 1)
          ? null
          : FloatingActionButton(
              onPressed: () async {
                await Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: (context) => RoutineScreen(null)));
                setState(() {});
              },
              child: Icon(
                Icons.add,
                color: kSecondColor,
                size: 30.0,
              ),
              elevation: 15.0,
            ),
      bottomNavigationBar: BottomNavigationBar(
        items: <BottomNavigationBarItem>[
          bottomItems(Icon(Icons.fitness_center_rounded), "Routines"),
          bottomItems(Icon(Icons.leaderboard_rounded), "Statistics"),
        ],
        currentIndex: _selectedIndex,
        onTap: (int index) => setState(() => _selectedIndex = index),
      ),
    );
  }
}

BottomNavigationBarItem bottomItems(Icon icon, String label) {
  return BottomNavigationBarItem(
    icon: icon,
    label: label,
  );
}

RoutinesWidget() 代码在这里:

import 'package:flutter/material.dart';
import 'package:workout_time/Services/db_crud_service.dart';
import 'package:workout_time/Screens/routine_screen.dart';
import 'package:workout_time/constants.dart';
import 'package:workout_time/Models/routine_model.dart';

class RoutinesWidget extends StatefulWidget {
  @override
  _RoutinesWidgetState createState() => _RoutinesWidgetState();
}

class _RoutinesWidgetState extends State<RoutinesWidget> {
  DBCRUDService helper;

  @override
  void initState() {
    super.initState();
    helper = DBCRUDService();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: helper.getRoutines(),
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        if (snapshot.hasData) {
          return ListView.builder(
            itemCount: snapshot.data.length,
            itemBuilder: (BuildContext context, int index) {
              Routine routine = Routine.fromMap(snapshot.data[index]);
              return Card(
                margin: EdgeInsets.all(1.0),
                child: ListTile(
                  leading: CircleAvatar(
                    child: Text(
                      routine.name[0],
                      style: TextStyle(
                          color: kThirdOppositeColor,
                          fontWeight: FontWeight.bold),
                    ),
                    backgroundColor: kAccentColor,
                  ),
                  title: Text(routine.name),
                  subtitle: Text(routine.exercises.join(",")),
                  trailing: IconButton(
                    icon: Icon(Icons.delete_rounded),
                    color: Colors.redAccent,
                    onPressed: () {
                      setState(() {
                        helper.deleteRoutine(routine.id);
                      });
                    },
                  ),
                  onTap: () => Navigator.push(
                      context,
                      MaterialPageRoute(
                          builder: (context) => RoutineScreen(routine))),
                ),
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(20.0)),
                color: kSecondColor,
              );
            },
          );
        } else {
          return Center(
            child: CircularProgressIndicator(),
          );
        }
      },
    );
  }
}

RoutineScreen() 代码在这里:

import 'package:flutter/material.dart';
import 'package:workout_time/Models/routine_model.dart';
import 'package:workout_time/Widgets/type_card_widget.dart';
import 'package:workout_time/constants.dart';
import 'package:workout_time/Services/db_crud_service.dart';

class RoutineScreen extends StatefulWidget {
  final Routine _routine;

  RoutineScreen(this._routine);

  @override
  _RoutineScreenState createState() => _RoutineScreenState();
}

class _RoutineScreenState extends State<RoutineScreen> {
  DBCRUDService helper;

  final _nameController = TextEditingController();

  final _descriptionController = TextEditingController();

  bool _type = true;

  int _cycles = 1;

  int _restBetweenExercises = 15;

  int _restBetweenCycles = 60;

  @override
  void initState() {
    super.initState();
    helper = DBCRUDService();
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
        appBar: AppBar(
          leading: IconButton(
            icon: Icon(Icons.arrow_back),
            onPressed: () => Navigator.pop(context),
          ),
          title: widget._routine != null
              ? Text(widget._routine.name)
              : Text("Create your routine"),
          actions: [
            IconButton(
              icon: Icon(Icons.done_rounded),
              onPressed: createRoutine,
            )
          ],
          bottom: TabBar(
            tabs: [
              Tab(
                text: "Configuration",
              ),
              Tab(
                text: "Exercises",
              ),
            ],
          ),
        ),
        body: TabBarView(children: [
          //_routine == null ? ConfigurationNewRoutine() : Text("WIDGET N° 1"),
          ListView(
            children: [
              Container(
                padding: EdgeInsets.all(15.0),
                child: Row(
                  children: [
                    Text(
                      "Name:",
                      style: TextStyle(
                        fontSize: 20.0,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    SizedBox(
                      width: 40.0,
                    ),
                    Expanded(
                      child: TextField(
                        textAlign: TextAlign.center,
                        controller: _nameController,
                      ),
                    ),
                  ],
                ),
              ),
              SizedBox(
                height: 20.0,
              ),
              Card(
                margin: EdgeInsets.all(15.0),
                color: kSecondColor,
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(20.0),
                ),
                child: Container(
                  padding: EdgeInsets.all(15.0),
                  child: Column(
                    children: [
                      Text(
                        "Type",
                        style: TextStyle(fontSize: 25.0),
                      ),
                      Row(
                        children: [
                          Expanded(
                            child: TypeCard(
                              Icons.double_arrow_rounded,
                              _type == true ? kFirstColor : kThirdColor,
                              () => setState(() => _type = true),
                              "Straight set",
                            ),
                          ),
                          Expanded(
                            child: TypeCard(
                              Icons.replay_rounded,
                              _type == false ? kFirstColor : kThirdColor,
                              () => setState(() => _type = false),
                              "Cycle",
                            ),
                          ),
                        ],
                      ),
                    ],
                  ),
                ),
              ),
              SizedBox(
                height: 20.0,
              ),
              Container(
                padding: EdgeInsets.all(15.0),
                child: Row(
                  children: [
                    Text(
                      "N° cycles:",
                      style: TextStyle(
                        fontSize: 20.0,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    SizedBox(
                      width: 40.0,
                    ),
                    Expanded(
                      child: Text("Hello"),
                    ),
                  ],
                ),
              ),
              SizedBox(
                height: 20.0,
              ),
            ],
          ),
          Text("WIDGET N° 2"),
        ]),
      ),
    );
  }

  void createRoutine() {
    List<String> _exercises = ["1", "2"];
    List<String> _types = ["t", "r"];
    List<String> _quantities = ["30", "20"];

    Routine routine = Routine({
      'name': _nameController.text,
      'description': "_description",
      'type': _type.toString(),
      'cycles': 1,
      'numberExercises': 2,
      'restBetweenExercises': 15,
      'restBetweenCycles': 60,
      'exercises': _exercises,
      'types': _types,
      'quantities': _quantities,
    });
    setState(() {
      helper.createRoutine(routine);
      Navigator.pop(context);
    });
  }
}

知道我该怎么做才能让它发挥作用吗?谢谢你

flutter
3个回答
1
投票

让事情变得简单

使用 Navigator.pop() 两次

这样当前班级和旧班级也被删除 从堆栈

然后使用 Navigator.push()


0
投票

当您推送新路由时,旧路由仍保留在堆栈中。新路线只是与旧路线重叠,就像旧路线之上的一层。然后当你弹出新路线时,它只会删除图层(新路线),旧路线将像以前一样显示。

现在您必须知道 Navigator.push() 是一个异步方法并返回一个 Future。它的工作原理基本上是当您执行 Navigator.push() 时,它将推送新路线并等待其弹出。然后,当新的路由被弹出时,它会向旧的路由返回一个值,并且当未来的回调将被执行时。

因此,您正在寻找的解决方案是在 Navigator.push() 之后添加一个像这样的未来回调:

Navigator.push(context,
                  MaterialPageRoute(builder: (context) => SettingsScreen())
).then((value){setState(() {});});   /// A callback which is executed after the new route will be popped. In that callback, you simply call a setState and refresh the page.

0
投票

可以联系我吗,我可以在聊天中解释你的疑惑

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