颤振突出显示当前选定的导航项目

时间:2020-03-22 18:09:26

标签: android ios iphone flutter dart

我为个人项目创建了一个入门工具包。

一切正常,但是我有个提示,无法在抽屉中突出显示当前选中的项目。

对于应该确定当前所选项目的代码,我有些困惑。enter image description here enter image description here

下面是我的代码!

class _MdDrawerState extends State<MdDrawer>
    with SingleTickerProviderStateMixin<MdDrawer> {
  final _animationDuration = const Duration(milliseconds: 350);

  AnimationController _animationController;
  Stream<bool> isDrawerOpenStream;
  StreamController<bool> isDrawerOpenStreamController;
  StreamSink<bool> isDrawerOpenSink;

  .....

  @override
  void dispose() {
    _animationController.dispose();
    isDrawerOpenStreamController.close();
    isDrawerOpenSink.close();
    super.dispose();
  }

  void onIconPressed() {
    final animationStatus = _animationController.status;
    final isAnimationCompleted = animationStatus == AnimationStatus.completed;

    .....
  }

  @override
  Widget build(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;

    return StreamBuilder<bool>(
      initialData: false,
      stream: isDrawerOpenStream,
      builder: (context, isLeftDrawerOpenedAsync) {
        return AnimatedPositioned(
          duration: _animationDuration,
          top: 0,
          bottom: 0,
          left: isLeftDrawerOpenedAsync.data ? 0 : -screenWidth,
          right: isLeftDrawerOpenedAsync.data ? 0 : screenWidth - 45,
          child: Row(
            children: <Widget>[
              Expanded(
                child: Container(
                  padding: const EdgeInsets.symmetric(horizontal: 20),
                  color: Theme.of(context).backgroundColor,
                  child: ListView(
                    children: <Widget>[
                      Column(
                        children: <Widget>[
                          SizedBox(
                            height: 30,
                          ),
                          ListTile(
                            title: Text('First - Last',
                                style: Theme.of(context).textTheme.headline),
                            subtitle: Text('something@gmail.com',
                                style: Theme.of(context).textTheme.subhead),
                            leading: CircleAvatar(
                              child: Icon(
                                Icons.perm_identity,
                                color: Theme.of(context).iconTheme.color,
                              ),
                              radius: 40,
                            ),
                          ),
                          Divider(
                            height: 30,
                          ),
                          MdNavItem(
                            icon: Icons.home,
                            title: 'Home',
                            onTap: () {
                              onIconPressed();
                              BlocProvider.of<MdNavBloc>(context)
                                  .add(NavigationEvents.HomeClickedEvent);
                            },
                          ),
                          MdNavItem(
                            icon: Icons.account_box,
                            title: 'Account',
                            onTap: () {
                              onIconPressed();
                              BlocProvider.of<MdNavBloc>(context)
                                  .add(NavigationEvents.AccountClickedEvent);
                            },
                          ),
                          MdNavItem(
                            icon: Icons.shopping_basket,
                            title: 'Orders',
                            onTap: () {
                              onIconPressed();
                              BlocProvider.of<MdNavBloc>(context)
                                  .add(NavigationEvents.OrderClickedEvent);
                            },
                          ),
                          MdNavItem(
                            icon: Icons.card_giftcard,
                            title: 'Wishlist',
                            onTap: () {
                              onIconPressed();
                              BlocProvider.of<MdNavBloc>(context)
                                  .add(NavigationEvents.WishlistClickedEvent);
                            },
                          ),
                          Divider(
                            height: 30,
                          ),
                          MdNavItem(
                            icon: Icons.settings,
                            title: 'Settings',
                            onTap: () {
                              onIconPressed();
                              BlocProvider.of<MdNavBloc>(context)
                                  .add(NavigationEvents.SettingsClickedEvent);
                            },
                          ),
                          MdNavItem(
                            icon: Icons.exit_to_app,
                            title: 'Logout',
                          ),
                          Divider(
                            height: 45,
                          ),
                        ],
                      ),
                    ],
                  ),
                ),
              ),
              ......
            ],
          ),
        );
      },
    );
  }
}

还有MdNavItem类

class MdNavItem extends StatelessWidget {
  final IconData icon;
  final String title;
  final Function onTap;

  const MdNavItem({this.icon, this.title, this.onTap});

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Container(
          color: Theme.of(context).backgroundColor,
          child: Row(
            children: <Widget>[
              Icon(
                icon,
                size: 25,
                color: Theme.of(context).iconTheme.color,
              ),
              SizedBox(
                width: 20,
              ),
              Text(
                title,
                style: Theme.of(context).textTheme.headline,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

1 个答案:

答案 0 :(得分:0)

编辑:

第一种方法:

将此代码添加到您的抽屉中:

class _MdDrawerState extends State<MdDrawer>
    with SingleTickerProviderStateMixin<MdDrawer> {
  final _animationDuration = const Duration(milliseconds: 350);

  AnimationController _animationController;
  Stream<bool> isDrawerOpenStream;
  StreamController<bool> isDrawerOpenStreamController;
  StreamSink<bool> isDrawerOpenSink;


  final List<bool> isTaped = [true, false, false, false, false];  // the first is true because when the app
                                                                  //launch the home needs to be in red(or the
                                                                  //color you choose)

  void changeHighlight(int index){
    for(int indexTap = 0; indexTap < isTaped.length; indexTap++) {
      if (indexTap == index) {
        isTaped[index] = true;                                    //used to change the value of the bool list
      } else {
        isTaped[indexTap] = false;
      }
    }
  }

  .....

  @override
  void dispose() {
    _animationController.dispose();
    isDrawerOpenStreamController.close();
    isDrawerOpenSink.close();
    super.dispose();
  }

  void onIconPressed() {
    final animationStatus = _animationController.status;
    final isAnimationCompleted = animationStatus == AnimationStatus.completed;

    .....
  }

  @override
  Widget build(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;

    return StreamBuilder<bool>(
      initialData: false,
      stream: isDrawerOpenStream,
      builder: (context, isLeftDrawerOpenedAsync) {
        return AnimatedPositioned(
          duration: _animationDuration,
          top: 0,
          bottom: 0,
          left: isLeftDrawerOpenedAsync.data ? 0 : -screenWidth,
          right: isLeftDrawerOpenedAsync.data ? 0 : screenWidth - 45,
          child: Row(
            children: <Widget>[
              Expanded(
                child: Container(
                  padding: const EdgeInsets.symmetric(horizontal: 20),
                  color: Theme.of(context).backgroundColor,
                  child: ListView(
                    children: <Widget>[
                      Column(
                        children: <Widget>[
                          SizedBox(
                            height: 30,
                          ),
                          ListTile(
                            title: Text('First - Last',
                                style: Theme.of(context).textTheme.headline),
                            subtitle: Text('something@gmail.com',
                                style: Theme.of(context).textTheme.subhead),
                            leading: CircleAvatar(
                              child: Icon(
                                Icons.perm_identity,
                                color: Theme.of(context).iconTheme.color,
                              ),
                              radius: 40,
                            ),
                          ),
                          Divider(
                            height: 30,
                          ),
                          MdNavItem(
                            wasTaped: isTaped[0],
                            icon: Icons.home,
                            title: 'Home',
                            onTap: () {
                              onIconPressed();
                              BlocProvider.of<MdNavBloc>(context)
                                  .add(NavigationEvents.HomeClickedEvent);
                              changeHighlight(0);
                            },
                          ),
                          MdNavItem(
                            wasTaped: isTaped[1],
                            icon: Icons.account_box,
                            title: 'Account',
                            onTap: () {
                              onIconPressed();
                              BlocProvider.of<MdNavBloc>(context)
                                  .add(NavigationEvents.AccountClickedEvent);
                              changeHighlight(1);
                            },
                          ),
                          MdNavItem(
                            wasTaped: isTaped[2],
                            icon: Icons.shopping_basket,
                            title: 'Orders',
                            onTap: () {
                              onIconPressed();
                              BlocProvider.of<MdNavBloc>(context)
                                  .add(NavigationEvents.OrderClickedEvent);
                              changeHighlight(2);
                            },
                          ),
                          MdNavItem(
                            wasTaped: isTaped[3],
                            icon: Icons.card_giftcard,
                            title: 'Wishlist',
                            onTap: () {
                              onIconPressed();
                              BlocProvider.of<MdNavBloc>(context)
                                  .add(NavigationEvents.WishlistClickedEvent);
                              changeHighlight(3);
                            },
                          ),
                          Divider(
                            height: 30,
                          ),
                          MdNavItem(
                            wasTaped: isTaped[4],
                            icon: Icons.settings,
                            title: 'Settings',
                            onTap: () {
                              onIconPressed();
                              BlocProvider.of<MdNavBloc>(context)
                                  .add(NavigationEvents.SettingsClickedEvent);
                              changeHighlight(4);
                            },
                          ),
                          MdNavItem(
                            icon: Icons.exit_to_app,
                            title: 'Logout',
                          ),
                          Divider(
                            height: 45,
                          ),
                        ],
                      ),
                    ],
                  ),
                ),
              ),
              ......
            ],
          ),
        );
      },
    );
  }
}

然后将其发送到您的MdNavItem:

class MdNavItem extends StatelessWidget {
  final IconData icon;
  final String title;
  final Function onTap;
  final bool wasTaped;     //receiving the bool value (if was taped or not)

  const MdNavItem({this.icon, this.title, this.onTap, this.wasTaped});

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Container(
          color: Theme.of(context).backgroundColor,
          child: Row(
            children: <Widget>[
              Icon(
                icon,
                size: 25,
                color: wasTaped ? Colors.red : Theme.of(context).iconTheme.color, //the condition to change the color
              ),
              SizedBox(
                width: 20,
              ),
              Text(
                title,
                style: wasTaped ? TextStyle(
                  color: Colors.red,
                ) : Theme.of(context).textTheme.headline,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

旧答案,第二种方式:

放置PageView的第一个屏幕:

class FirstScreen extends StatelessWidget {

  final PageController pageController = PageController(initialPage: 0);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Kit App'),
      ),
      drawer: CustomDrawer(
        pageController: pageController,
      ),
      body: PageView(
        controller: pageController,
        physics: NeverScrollableScrollPhysics(), //to prevent scroll
        children: <Widget>[
          HomeScreen(),
          AccountScreen(),   //your pages
          OrdersScreen(),
          WishListScreen(),
        ],
      ),
    );
  }
}

CustomDrawer:

class CustomDrawer extends StatelessWidget {
  CustomDrawer({@required this.pageController});

  final PageController pageController;

  @override
  Widget build(BuildContext context) {
    return Drawer(
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 20),
        child: Column(
          children: <Widget>[
            DrawerItem(
              onTap: (){
                Navigator.pop(context); //to close the drawer
                pageController.jumpToPage(0);
              },
              leading: Icons.home,
              title: 'Home',
              index: 0,
              controller: pageController,
            ),
            DrawerItem(
              onTap: (){
                Navigator.pop(context);
                pageController.jumpToPage(1);
              },
              leading: Icons.account_box,
              title: 'Account',
              index: 1,
              controller: pageController,
            ),
            DrawerItem(
              onTap: (){
                Navigator.pop(context);
                pageController.jumpToPage(2);
              },
              leading: Icons.shopping_cart,
              title: 'Orders',
              index: 2,
              controller: pageController,
            ),
            DrawerItem(
              onTap: (){
                Navigator.pop(context);
                pageController.jumpToPage(3);
              },
              leading: Icons.card_travel,
              title: 'Wishlist',
              index: 3,
              controller: pageController,
            ),
          ],
        ),
      ),
    );
  }
}

和DrawerItem,放置更改项目颜色的条件:

class DrawerItem extends StatelessWidget {
  DrawerItem({
    @required this.onTap,
    @required this.leading,
    @required this.title,
    @required this.index,
    @required this.controller,
  });

  final VoidCallback onTap;
  final IconData leading;
  final String title;
  final int index;
  final PageController controller;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,
      child: ListTile(
        leading: Icon(
          leading,
          color: controller.page.round() == index ? Colors.red : Colors.grey,
        ),
        title: Text(
          title,
          style: TextStyle(
            color: controller.page.round() == index ? Colors.red : Colors.grey,
          ),
        ),
      ),
    );
  }
}

结果: enter image description here

现在,您只需要在代码中实现它即可。