如何在Flutter中为底部导航栏图标提供渐变

时间:2018-10-25 05:45:34

标签: android dart flutter

我有一个带有四个图标的底部导航栏,默认颜色是我的应用程序的主题颜色(主色)。我想将选定的图标更改为渐变色,所以我写了一个带有装饰的容器,但是它不能正常工作,任何人都可以帮助我,它应该如图所示。谢谢

import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:io';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:material_search/material_search.dart';
import 'dart:ui' as ui;


class DrawerItem {
  String title;
  IconData icon;
  DrawerItem(this.title, this.icon);
}


class HomeScreen extends StatefulWidget {

  final drawerItems = [
    new DrawerItem("Dashboard", Icons.dashboard),
    new DrawerItem("Live Tracking", Icons.track_changes),
    new DrawerItem("Notifications", Icons.notifications),
    new DrawerItem("Account Details", Icons.exit_to_app),
    // new DrawerItem("Reports", Icons.dock),
  ];

  @override
  State<StatefulWidget> createState() {
    return new HomeScreenState();
  }
}


class HomeScreenState extends State<HomeScreen> {

  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  final JsonDecoder _decoder = new JsonDecoder();

  String pageValue = 'Dashboard';

  IconData selectedItem = Icons.dashboard ;
  List<IconData> itemsList = [
      Icons.dashboard, Icons.location_on, Icons.notifications, Icons.account_circle,
  ];

  //Vehicles Data
  final _vehicleNumbers = [];
  String vehicleNum = '';
  static String _id;
  String value;
  String getValue;
  dynamic vehicleData;
  var vehiclesLength = 0;
  var addVehiclesLength = 0;
  int bottomNavBarIndex = 0;

  Widget appBarTitle = new Text("Dashboard",
    style: TextStyle(
      fontSize: 24.0,
      // fontWeight: FontWeight.bold,
      color: Colors.grey[600]
    ),
    textAlign: TextAlign.center
  );
  bool search = false;

  //UserDetails
  static dynamic user = new User();
  String key = user.getKey();

   int _selectedDrawerIndex = 0;

  _getDrawerItemWidget(int pos) {
    switch (pos) {
      case 0:
        return new Dashboard();
      case 1:
        return new LiveTracking();
      case 2:
        return new Notifications();
      case 3:
        return new AccountProfile();
      default:
        return new Text("Error");
    }
  }

  _onSelectItem(int index) {

    if(widget.drawerItems[_selectedDrawerIndex].title == 'Dashboard'){
      this.appBarTitle = new Text(widget.drawerItems[_selectedDrawerIndex].title,
        style: TextStyle(
          fontSize: 24.0,
          // fontWeight: FontWeight.bold,
          color: Colors.grey[600],
        ),
        textAlign: TextAlign.center
      );
      this.pageValue = widget.drawerItems[_selectedDrawerIndex].title;
    }
    else if(widget.drawerItems[_selectedDrawerIndex].title == 'Live Tracking'){
      this.appBarTitle = new Text(widget.drawerItems[_selectedDrawerIndex].title,
        style: TextStyle(
          fontSize: 24.0,
          // fontWeight: FontWeight.bold,
          color: Colors.grey[600],
        ),
        textAlign: TextAlign.center
      );
      this.pageValue = widget.drawerItems[_selectedDrawerIndex].title;
    }
    else if(widget.drawerItems[_selectedDrawerIndex].title == 'Notifications'){
      this.appBarTitle = new Text(widget.drawerItems[_selectedDrawerIndex].title,
        style: TextStyle(
          fontSize: 24.0,
          // fontWeight: FontWeight.bold,
          color: Colors.grey[600],
        ),
        textAlign: TextAlign.center
      );
      this.pageValue = widget.drawerItems[_selectedDrawerIndex].title;
    }
    else if(widget.drawerItems[_selectedDrawerIndex].title == 'Account Details'){
      this.appBarTitle = new Text(widget.drawerItems[_selectedDrawerIndex].title,
        style: TextStyle(
          fontSize: 24.0,
          // fontWeight: FontWeight.bold,
          color: Colors.grey[600],
        ),
        textAlign: TextAlign.center
      );
      this.pageValue = widget.drawerItems[_selectedDrawerIndex].title;
    }
  } 

  //Vehicle List Data
  Future<dynamic> getVehiclesData() async {
    var response = await http.get(
        Uri.encodeFull(API.dashboardData),
        headers: {HttpHeaders.AUTHORIZATION: "Basic " + key});
    final String res = response.body;
    vehicleData = _decoder.convert(res);
    vehiclesLength = vehicleData["_items"].length;

    setState(() {
      addVehiclesLength =  vehiclesLength;
      for(int i=0;i<addVehiclesLength;i++){
        if(vehicleData["_items"][i]["vehicle"] != null){
          _vehicleNumbers.add(vehicleData["_items"][i]["vehicle"]["registration"].toString());
        }
        else{
          _vehicleNumbers.add('New vehicle');
        }
      }
    });
  }

  _buildMaterialSearchPage(BuildContext context) {
    return new MaterialPageRoute<String>(
      settings: new RouteSettings(
        name: 'material_search',
        isInitialRoute: false,
      ),
      builder: (BuildContext context) {
        return new Material(
          child: new MaterialSearch<String>(
            placeholder: 'Search',
            results: _vehicleNumbers.map((getValue) => new MaterialSearchResult<String>(
              value: getValue,
              text: "$getValue",
            )).toList(),
            filter: (dynamic value, String criteria) {
              return value.toLowerCase().trim()
                .contains(new RegExp(r'' + criteria.toLowerCase().trim() + ''));
            },
            onSelect: (dynamic value) => Navigator.of(context).pop(value),
          ),
        );
      }
    );
  }




  //Logout functionality... 
  void _logout() async {
    var db = new DatabaseHelper();
    await db.deleteUsers();
  }


  //To initiate state of the class before loading that paticular page...
  @override
  void initState() {
    super.initState();
    print('came to init state');
    getVehiclesData();
  }

  _showMaterialSearch(BuildContext context) {
    if(pageValue != null && pageValue == 'Dashboard'){
    Navigator.of(context)
      .push(_buildMaterialSearchPage(context))
      .then((dynamic value) {
        setState(() => vehicleNum = value as String);
        String check = vehicleNum;
        // print('check = $check');
        if(check != '' && check != null){
          check = '';
          _id = _getId(vehicleNum);
          print(_id);
          Navigator.push(context, new MaterialPageRoute(builder: (context) => new SingleVehicleDashboard(value:_id)));
        }
      });
    }
    else if(pageValue != null && pageValue == 'Live Tracking'){
    Navigator.of(context)
      .push(_buildMaterialSearchPage(context))
      .then((dynamic value) {
        setState(() => vehicleNum = value as String);
        String check = vehicleNum;
        // print('check = $check');
        if(check != '' && check != null){
          check = '';
          _id = _getId(vehicleNum);
          print(_id);
          Navigator.push(context, new MaterialPageRoute(builder: (context) => new SingleVehicleDashboard(value:_id)));
        }
      });
    } 
  }

  String _getId(String vehicleNum){
    String id;
    for(int i=0;i<addVehiclesLength;i++){
      if(vehicleData["_items"][i]["vehicle"] != null){
        if(vehicleData["_items"][i]["vehicle"]["registration"].toString().contains(vehicleNum)){
          id = vehicleData["_items"][i]["vehicle"]["_id"];
        }
      }
    }
    return id;
  }

  @override
  Widget build(BuildContext context) {

    return new Scaffold(
      key: _scaffoldKey,
      appBar: new AppBar(
        backgroundColor:
        widget.drawerItems[_selectedDrawerIndex].title == 'Account Details'?
        Colors.grey[200]:Colors.white,
        iconTheme: new IconThemeData(color: Colors.black),
        // here we display the title corresponding to the fragment
        // you can instead choose to have a static title
        title: new Center(child: appBarTitle),
        actions: <Widget>[
          widget.drawerItems[_selectedDrawerIndex].title == 'Dashboard' || widget.drawerItems[_selectedDrawerIndex].title == 'Live Tracking' ?
          new IconButton(
            onPressed: () {
              search = true;
              _showMaterialSearch(context);
            },
            tooltip: 'Search',
            icon: new Icon(Icons.search),
          ) : new Text(''),
          widget.drawerItems[_selectedDrawerIndex].title == 'Account Details' ?
          new IconButton(
            onPressed: () {
              _logout();
              Navigator.of(context).pushReplacementNamed("/login");
            },
            tooltip: 'Search',
            icon: new Icon(Icons.exit_to_app),
          ) : new Text(''),
          widget.drawerItems[_selectedDrawerIndex].title == 'Notifications' ?
          new Text(''):new Text('')
        ],
        elevation:
        widget.drawerItems[_selectedDrawerIndex].title == 'Notifications' ?
        2.0:0.0,
      ),

      bottomNavigationBar: BottomNavigationBar(
        currentIndex: bottomNavBarIndex,
        onTap: (int index) {
          setState(() {
            bottomNavBarIndex = index;
            _selectedDrawerIndex = index;
            _onSelectItem(index);
            selectedItem = itemsList[index];
            print(index);
          });
        },
        items: itemsList.map((data) {
          return BottomNavigationBarItem(
            icon: selectedItem == data ? ShaderMask(
              blendMode: BlendMode.srcIn,
              shaderCallback: (Rect bounds) {
                return ui.Gradient.linear(
                  Offset(4.0, 24.0),
                  Offset(24.0, 4.0),
                  [Colors.greenAccent[200],Colors.blueAccent[200]]
                );
              },
              child: Icon(data),
              ) : Icon(data, color: Colors.grey[600]),
              title: Container(),
            );
          }).toList()
        ),


      // bottomNavigationBar: new BottomAppBar(
      //   child: BottomNavigationBar(
      //     currentIndex: bottomNavBarIndex,
      //     onTap: (int index){
      //       setState(() {
      //         bottomNavBarIndex = index;
      //         _selectedDrawerIndex = index;
      //         _onSelectItem(index);
      //       });
      //     },
      //     items: 
      //     [
      //       BottomNavigationBarItem(
      //         icon: new Icon(Icons.dashboard),
      //         title: new Text(''),
      //       ),
      //       BottomNavigationBarItem(
      //         icon: new Icon(Icons.location_on),
      //         title: new Text(''),
      //       ),
      //       BottomNavigationBarItem(
      //         icon: new Icon(Icons.notifications),
      //         title: new Text(''),
      //       ),
      //       BottomNavigationBarItem(
      //         icon: new Icon(Icons.account_circle),
      //         title: new Text(''),
      //       ),
      //     ],
      //   ),
      // ),  
      // endDrawer: new Drawer(
      //     child: Column(
      //       children: <Widget>[
      //         new Text(
      //           '',
      //           style: new TextStyle(
      //             fontSize: 30.0,
      //             fontWeight: FontWeight.bold,
      //           ),
      //           textAlign: TextAlign.center,
      //         ),
      //         new Text(
      //           'Notifications',
      //           style: new TextStyle(
      //             fontSize: 24.0,
      //             fontWeight: FontWeight.bold,
      //           ),
      //           textAlign: TextAlign.center,
      //         ),
      //         Flexible(
                // child: ListView(
                //   children: List.generate(notificationsLength,
                //     (i) => new Container(
                //       decoration: new BoxDecoration(
                //         border: new Border(
                //             bottom: BorderSide(
                //       color: Colors.grey[300],
                //     ))),
                //       height: 100.0,
                //       padding: EdgeInsets.fromLTRB(8.0, 5.0, 8.0, 5.0),
                //       child: new Text(
                //         addNotifications["_items"][i]["alert_message"],
                //         style: new TextStyle(fontSize: 14.0),
                //       ),
                //     )),
                // ),
      //         )
      //       ],
      //     ),
      //   ),
      body: new Center(
        child:_getDrawerItemWidget(_selectedDrawerIndex),
      ),
    );
  }
}

我想这样显示我的底部导航栏。 enter image description here

这就是我现在所拥有的... enter image description here

3 个答案:

答案 0 :(得分:2)

您可以按如下所示将颜色应用于您自己的渐变颜色的图标:

1)-创建一个将基本渐变应用于任何图标的类

class RadiantGradientMask extends StatelessWidget {
  RadiantGradientMask({this.child});
  final Widget child;

  @override
  Widget build(BuildContext context) {
    return ShaderMask(
      shaderCallback: (Rect bounds) {
        return RadialGradient(
          center: Alignment.bottomLeft,
          radius: 0.5,
          colors: <Color>[
            appThemeColor,
            Colors.amberAccent
          ],
          tileMode: TileMode.mirror,
        ).createShader(bounds);
      },
      child: child,
    );
  }
}

2)-为图标设置渐变

activeIcon: RadiantGradientMask(child: Icon(
  Icons.location_city,
  size: 30,
  color: Colors.white,
 )
)

这是我的输出

Here is my output

注意:Click Here to see the Example

答案 1 :(得分:1)

您想要的东西可以在-ShaderMask的帮助下实现-您可以使用“各种渐变”来玩,并达到您想要的目的。 例如,检查以下代码:

bottomNavigationBar: BottomNavigationBar(
        currentIndex: bottomNavBarIndex,
        onTap: (int index) {
          setState(() {
            bottomNavBarIndex = index;
            _selectedDrawerIndex = index;
            _onSelectItem(index);
          });
        },
        items: [
          BottomNavigationBarItem(
            activeIcon: ShaderMask(
              shaderCallback: (Rect bounds) {
                return RadialGradient(
                  center: Alignment.topLeft,
                  radius: 0.5,
                  colors: <Color>[
                    Colors.greenAccent[200],
                    Colors.blueAccent[200]
                  ],
                  tileMode: TileMode.repeated,
                ).createShader(bounds);
              },
              child: Icon(Icons.dashboard),
            ),
            icon: new Icon(Icons.dashboard, color: Colors.grey),
            title: new Text(''),
          ),
          BottomNavigationBarItem(
            activeIcon: ShaderMask(
              shaderCallback: (Rect bounds) {
                return RadialGradient(
                  center: Alignment.topLeft,
                  radius: 1.0,
                  colors: <Color>[
                    Colors.greenAccent[200],
                    Colors.blueAccent[200]
                  ],
                  tileMode: TileMode.mirror,
                ).createShader(bounds);
              },
              child: Icon(Icons.location_on),
            ),
            icon: Icon(Icons.location_on, color: Colors.grey),
            title: new Text(''),
          ),
          BottomNavigationBarItem(
            activeIcon: ShaderMask(
              shaderCallback: (Rect bounds) {
                return RadialGradient(
                  center: Alignment.topLeft,
                  radius: 1.0,
                  colors: <Color>[
                    Colors.greenAccent[200],
                    Colors.blueAccent[200]
                  ],
                  tileMode: TileMode.mirror,
                ).createShader(bounds);
              },
              child: Icon(Icons.notifications),
            ),
            icon: Icon(Icons.notifications, color: Colors.grey),
            title: Text(''),
          ),
          BottomNavigationBarItem(
            activeIcon: ShaderMask(
              shaderCallback: (Rect bounds) {
                return RadialGradient(
                  center: Alignment.topLeft,
                  radius: 1.0,
                  colors: <Color>[
                    Colors.greenAccent[200],
                    Colors.blueAccent[200]
                  ],
                  tileMode: TileMode.mirror,
                ).createShader(bounds);
              },
              child: Icon(Icons.account_circle),
            ),
            icon: Icon(Icons.account_circle, color: Colors.grey),
            title: Text(''),
          ),
        ],
      ),

答案 2 :(得分:0)

import 'dart:ui' as ui;

IconData selectedItem = Icons.dashboard ;
List<IconData> itemsList = [
    Icons.dashboard, Icons.location_on, Icons.notifications, Icons.account_circle,
];

...
@override
Widget build(BuildContext context) {
return new Scaffold(
  key: _scaffoldKey,
  appBar: AppBar(...),
bottomNavigationBar: BottomNavigationBar(
      onTap: (int index) {
        setState(() {
          selectedItem = itemsList[index];
        });
      },
      items: itemsList.map((data) {
        return BottomNavigationBarItem(
          icon: selectedItem == data ? ShaderMask(
            blendMode: BlendMode.srcIn,
            shaderCallback: (Rect bounds) {
              return ui.Gradient.linear(
                Offset(4.0, 24.0),
                Offset(24.0, 4.0),
                [
                  Colors.blue[200],
                  Colors.greenAccent,
                ],
              );
            },
            child: Icon(data),
          ) : Icon(data, color: Colors.grey),
          title: Container(),
        );
      }).toList()
  ),