颤振避免重新打开抽屉页面

时间:2019-06-03 13:23:27

标签: flutter dart flutter-layout

我有一个导航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,我不希望抽屉再次打开设置,因为我已经在里面!

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

3 个答案:

答案 0 :(得分:1)

enter image description here


这是我的操作方式(完整代码)

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),
    );
  }
}

答案 1 :(得分:0)

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

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),
     ...

我希望能帮上忙。

答案 2 :(得分:0)

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

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);
      }
    },