Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make BottomNavigationBarItem not clickable and disable tap splash effect?

Tags:

flutter

I have BottomNavigationBar with 5 items and also FloatingActionButton that should change 3rd item 'Photo'.

So I need if user press on central BottomNavigationBarItem 'Photo' it didn't affect switching to this tab.

How can I disable clicking on specific BottomNavigationBarItem?

BottomNavigationBar with FloatingActionButton

And here is my code:

import 'package:flutter/material.dart';

class MainPage extends StatefulWidget {
  @override
  _MainPageState createState() => new _MainPageState();
}

class PageInfoData {
  final String title;
  final IconData iconData;

  const PageInfoData(this.title, this.iconData);
}

class _MainPageState extends State<MainPage> {
  int _selectedIndex = 0;

  static const List<PageInfoData> pageInfo = [
    PageInfoData('History', Icons.swap_horiz),
    PageInfoData('Download', Icons.file_download),
    PageInfoData('Photo ', null),
    PageInfoData('Upload', Icons.file_upload),
    PageInfoData('Settings', Icons.settings)
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: false,
        title: Text("Menu"),
        actions: <Widget>[IconButton(icon: Icon(Icons.search, color: Colors.white,),)],
      ),
      body: Center(child: Text('Index$_selectedIndex: ${pageInfo[_selectedIndex].title}')),
      backgroundColor: Colors.white,
      bottomNavigationBar: BottomNavigationBar(
        items: new List<BottomNavigationBarItem>.generate(pageInfo.length, (int index) {
          PageInfoData curPageInfo = pageInfo[index];
          return BottomNavigationBarItem(icon: Icon(curPageInfo.iconData, size: 30.0), title: Text(curPageInfo.title, style: TextStyle(fontSize: 9.0),));
        }),
        type: BottomNavigationBarType.fixed,
        unselectedItemColor: const Color(0xff797979),
        fixedColor: Theme.of(context).primaryColor,
        backgroundColor: const Color(0xffe2e2e2),
        currentIndex: _selectedIndex,
        showUnselectedLabels: true,
        onTap: _onItemTapped,
      ),

      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      floatingActionButton: FloatingActionButton(
        backgroundColor: Color(0xffa2a5a4),
        child: Icon(Icons.photo_camera, size: 40.0,),
          onPressed: null),
    );
  }

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }
}

UPDATE:

Problem almost solved (thank you @ibhavikmakwana) by changing _onItemTapped function

void _onItemTapped(int index) {
    if (index != 2) {
      setState(() {
        _selectedIndex = index;
      });
    }
  }

But it solved not completely. When I tap photo label it still show me a tap splash effect. Can I disable a tap splash effect?

enter image description here

like image 323
Maxim Milyutin Avatar asked May 02 '19 09:05

Maxim Milyutin


4 Answers

I had the same issue as yours. In my case, I just only want to apply it on bottomNavigationBar, because I have splash effect on another widget.

I fixed it using this code below:

bottomNavigationBar: Theme(
    data: ThemeData(
      splashColor: Colors.transparent,
      highlightColor: Colors.transparent,
    ),
    child: BottomNavigationBar(),
),
like image 107
William Sumitro Avatar answered Nov 13 '22 08:11

William Sumitro


You can do something like below:

Your bottomNavigationBar

bottomNavigationBar: BottomNavigationBar(
  items: [
    BottomNavigationBarItem(
      ...
    ),
    BottomNavigationBarItem(
      ...
    ),
    BottomNavigationBarItem(
      ...
    ),
  ],
  onTap: navigationTapped,
  currentIndex: _page,
),

You can add the conditional check whether the page index match with the current index than don't do anything and return from that point.

Like page == index

Where, index is position of the BottomNavigationBarItem

void navigationTapped(int page) {
  if (page == 1) {
    return;
  } else {
    setState(() {
      _selectedIndex = page;
    });
  }
}
like image 34
ibhavikmakwana Avatar answered Nov 13 '22 08:11

ibhavikmakwana


To extend the correct answers given here, the correct way to disable splash effect, you should copy the existing app ThemeData and override only the splashColor and highlighColor properties.

Otherwise the other app ThemeData properties will be lost.

Wrap your widget with Theme widget and instead:

Theme(
  data: ThemeData(
    splashColor: Colors.transparent,
    highlightColor: Colors.transparent,
  ),
  child: YourWidget(),
);

Use:

Theme(
  data: Theme.of(context).copyWith(
    splashColor: Colors.transparent,
    highlightColor: Colors.transparent,
  ),
  child: YourWidget(),
);
like image 4
Juvi Avatar answered Nov 13 '22 06:11

Juvi


Maybe you can try this to disable splash effect:

Change the splashColor or splashFactory in ThemeData to Colors.transparent.

Reference: How to disable default Widget splash effect in Flutter?

like image 3
leemuljadi Avatar answered Nov 13 '22 06:11

leemuljadi