如何防止导航器推送刷新屏幕

Posted

技术标签:

【中文标题】如何防止导航器推送刷新屏幕【英文标题】:How can I prevent Navigator push from refreshing the screen 【发布时间】:2020-02-28 17:41:23 【问题描述】:

我正在编写一个颤振程序,用户应该从 DropdownButtonFormField 中选择一个值。做出选择后,选择应显示在下拉列表中。我使用推送路由从使用选择的第二个屏幕获取数据。我的问题是在选择选项后,页面刷新,因此不会在下拉列表中显示所选值。

下面是我的代码:

我在一个名为 shared.dart 的文件中创建了 Dropdownbuttonformfield,这样我就可以在多个文件中调用它:

  class UserDropdownList extends StatefulWidget 
  @override
  _UserDropdownListState createState() => _UserDropdownListState();
   
  class _UserDropdownListState extends State<UserDropdownList> 

  String currentUser;

  @override
  Widget build(BuildContext context) 

    final user = Provider.of<List<User>>(context) ?? [];


    return DropdownButtonFormField(
      isExpanded: true,
      decoration: textInputDecoration,
      value: currentUser,

      hint: Text(
        'Incoming Officer',
      ),
      onChanged: (val) 
        setState(() => currentUser = val);
        var route = MaterialPageRoute(
          builder: (BuildContext context) =>
          FinalForm(chosenUser: currentUser,)
          );
          Navigator.of(context).push(route);
      ,
      // onChanged: (val) => setState(() => currentUser = val),
      items: user.map((user)
        return DropdownMenuItem(
          value: user.userId,
          child: Text(user.name)
        );
      ).toList(),
    );
      
    

然后我像这样在我的主页中调用自定义按钮

class FinalForm extends StatefulWidget 

//code for importing selected user
  final String chosenUser;
  FinalForm(Key key, this.chosenUser) : super (key: key);

  @override
  _FinalForm createState() => _FinalFormState();


class _FinalFormState extends State<FinalForm> 



  @override
  Widget build(BuildContext context) 



    return Scaffold(
      appBar: AppBar(
        title: Text('Final Form')
      ),
      body: Form( 
        child: Center(
          child: ListView(
            shrinkWrap: true,
            padding: EdgeInsets.fromLTRB(5, 5, 5, 5),
            children: <Widget>[

            SizedBox(height: 20.0),

            Align(
              child: Text( 
                'Select Incoming Officer',
                style: TextStyle(
                  fontSize: 20.0,
                  fontWeight: FontWeight.bold,
                  color: Colors.blueAccent,
                ),
              )
            ),
            SizedBox(height: 20.0),

            StreamProvider<List<User>>.value(
              value: DatabaseService().users,
              child: UserDropdownList(),

            ),



            SizedBox(height: 20.0),
            Text("$widget.chosenUser"),

          ],),
        ),
      ),
    );
  

有没有办法将所选值保留在下拉菜单中或防止屏幕重新加载?

【问题讨论】:

如果您正在离开当前页面,页面重建有什么关系?就此而言,还有什么理由在这里打电话给setState 下拉列表是我自己创建的自定义小部件。我在另一个使用数据的有状态小部件的屏幕上调用它。我希望它只将数据推送到第二个屏幕,而不是重建整个东西 那么您可能不应该开始导航。不重建就无法导航(因为这会破坏导航的目的)。 不,你不能阻止它重建——你必须准备好随时调用build方法 在不重建的情况下推送数据的最佳方式是什么? 【参考方案1】:

如果您正在离开当前页面/视图,则丢失当前的下拉选择是有意义的。您可以将当前选择作为参数传递给 push 函数以在新页面上重新显示。小时

【讨论】:

问题是我没有从当前页面导航。我只是使用导航器将选定的数据推送到有状态小部件,我在其中调用自定义 Dropdownformfield。所以最终还是要显示Dropdown,刚才我需要它和数据 @David 你正在导航。这就是Navigator.push 所做的——导航。如果您只想移动数据,请不要使用它。 我将其用作最后一个选项,在不导航的情况下推送数据的最佳选择是什么? @David "如果您使用来自子 Widget 的 Navigator.pop,父 Widget 将始终被重建 - 您无法阻止它" @pskink 这就是我所意识到的,所以我被困在如何从我在一个有状态小部件中创建的下拉列表中移动一个字符串值并在另一个有状态小部件中使用它

以上是关于如何防止导航器推送刷新屏幕的主要内容,如果未能解决你的问题,请参考以下文章

Android 组件导航如何防止地图页面在每次点击时刷新

使用底部导航栏防止片段刷新

从第二个屏幕导航回来并刷新页面颤动时关闭 AlertDialog

React Native刷新屏幕/组件/更改状态

ASP.NET 如何防止页面的刷新

在ASP中如何防止用户频繁刷新网页