【问题标题】:Flutter avoid re-opening drawer pageFlutter避免重新打开抽屉页面
【发布时间】:2019-10-19 01:33:14
【问题描述】:

我有一个导航Drawer,其中的条目如下所示:

ListTile(
  onTap: () => doRoute(context, '/second'),
  title: Text(...),
),

doRoute的方法如下:

String _currentRoute = '/';

void doRoute(BuildContext context, String routename) {
    if (_currentRoute != routename) {
      Navigator.of(context).popAndPushNamed(routename);
      _currentRoute = routename;
    }
    else
      Navigator.of(context).pop();
}

我这样做是因为我不想打开同一个页面两次。假设我在抽屉里点击Settings。如果我再次打开抽屉并点击Settings 我不希望抽屉再次打开设置因为我已经在那里了!

我该怎么做?为什么字符串比较不起作用?

【问题讨论】:

  • 您是否尝试过同时打印_currentRouterouteName
  • 是的,但我不明白该怎么做
  • 你能分享一下结果吗?您在“设置”页面上时的值是什么?
  • 您是否将相同的抽屉添加到second 路由?

标签: flutter dart flutter-layout


【解决方案1】:


这是我的做法(完整代码)

void main() {
  runApp(
    MaterialApp(
      routes: {
        "/": (context) => HomePage(),
        "/settings": (context) => SettingsPage(),
      },
    ),
  );
}
String _currentRoute = "/";

Widget buildDrawer(context) {
  return Drawer(
    child: SafeArea(
      child: Column(
        children: <Widget>[
          ListTile(
            title: Text("Home"),
            onTap: () => doRoute(context, '/'),
          ),
          ListTile(
            title: Text("Settings"),
            onTap: () => doRoute(context, '/settings'),
          ),
        ],
      ),
    ),
  );
}

void doRoute(BuildContext context, String name) {
  if (_currentRoute != name)
    Navigator.pushReplacementNamed(context, name);
  else
    Navigator.pop(context);

  _currentRoute = name;
}

// Page 1 (HomePage)
class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Home")),
      body: Container(color: Colors.blue.withOpacity(0.5)),
      drawer: buildDrawer(context),
    );
  }
}

// Page 2 (SettingsPage)
class SettingsPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Settings")),
      body: Container(color: Colors.orange.withOpacity(0.5)),
      drawer: buildDrawer(context),
    );
  }
}

【讨论】:

  • 知道了!问题是我总是为每一页返回相同的抽屉
【解决方案2】:

我解决了,没有实例变量: 定义你的路线:

providers: providers,
  child: MaterialApp(
    title: Strings.appName,
    routes: <String, WidgetBuilder>{
      Strings.login: (BuildContext context) => LoginPage(),
      Strings.inicio: (BuildContext context) => HomePage(),
    }
...

然后,在您的 listItem 抽屉 onTap 函数中,您可以获得当前路线的名称:

class _ListItemDrawer extends StatelessWidget {
  final String icon;
  final String title;

  _ListItemDrawer({this.icon, this.title});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.fromLTRB(0, 40, 0, 0),
      child: ListTile(
        leading: Image.asset(
          icon,
          color: Colors.black,
          height: ScreenUtil().setHeight(100),
        ),
        title: Text(
          title,
          style: Styles.drawerTextStyle(context),
        ),
        onTap: () {
          Navigator.pop(context);
          final isCurrentPage = ModalRoute.of(context).settings.name == title;
          if(!isCurrentPage){
            Navigator.pushNamed(context, title);
          }
        },
      ),
    );
  }
}

您必须在您的路线中使用与您的 listItem 标题相同的字符串。即:

...
child: Drawer(
      child: Container(
    color: drawerGreyColor,
    child: ListView(
      padding: EdgeInsets.zero,
      children: <Widget>[
        _ListItemDrawer(
            icon: 'assets/images/home-icon.png',
            title: Strings.inicio),
     ...

希望对你有帮助。

【讨论】:

    【解决方案3】:

    我通过改变变量的状态解决了这个问题。

    settingPage.dart

    中定义一个全局变量
    bool clickableSettings = true;
    

    我的homePage.dart

      @override
      void initState() {
        print("Set clickableSettings is true");
        clickableSettings = true;
        super.initState();
      }
    

    点击设置时

    onPressed: () {
          if (clickableSettings == false) {
            print("clickableSettings is false");
          } else if (clickableSettings == true) {
            clickableSettings = false;
            Navigator.of(context).pushNamedAndRemoveUntil(
                '/setting', (Route<dynamic> route) => false);
          }
        },
    

    【讨论】:

      猜你喜欢
      • 2021-05-06
      • 2020-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-12
      • 2020-12-15
      • 2018-10-02
      相关资源
      最近更新 更多