Есть ли способ отобразить BottomNavigationBar при каждом просмотре? - PullRequest
0 голосов
/ 04 мая 2020

Я пытаюсь отобразить BottomNavigationBar для каждого моего просмотра, он работает, но это «тупой» способ сделать это ...

У меня есть пользовательский BottomNavigationBar, который я вставляю в каждое представление .

var selectedIndex = 0;
class CustomBottombar extends StatefulWidget {
  CustomBottombar({Key key}) : super(key: key);
  @override
  _CustomBottombarState createState() => _CustomBottombarState();
}

class _CustomBottombarState extends State<CustomBottombar> {
  List _viewList = [FirstView(), SecondView()];
  @override
  Widget build(BuildContext context) {
    return BottomNavigationBar(
      currentIndex: selectedIndex,
      onTap: _onItemTapped,
       items: _items,
    );
  }

  void _onItemTapped(int index) {
    setState(() {
      selectedIndex = index;
      Navigator.of(context).popUntil((route) => route.isFirst
      );
      Navigator.pushReplacement(
              context,
              MaterialPageRoute(builder: (context) => _viewList[index]),
            );
    });
  }
  final _items = [
BottomNavigationBarItem(
            icon: Icon(
              Icons.refresh,
              color: Color(0xFFACACAC),
              size: 35,
            ),
            title: Text("first")),
BottomNavigationBarItem(
          icon: Icon(
            Icons.phone,
            color: Color(0xFFACACAC),
            size: 35,
          ),
          title: Text("second"),
        ),
BottomNavigationBarItem(
          icon: Icon(
            Icons.add_shopping_cart,
            color: Color(0xFFACACAC),
            size: 35,
          ),
          title: Text("thrid"),
        ),

]; }

в функции _onItemTapped я вытаскиваю все из «стека навигации», а затем отображаю экран, который находится в моих элементах.

в моем FirstView () У меня есть этот код

class FirstView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: CustomAppBar(""),
      bottomNavigationBar: CustomBottombar(),
      endDrawer: CustomDrawer(),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => ContactView()),
            );
          },
          child: Text('First'),
        ),
      ),
    );
  }
}

Теперь я хочу перейти к «ContactView», который не является элементом в BottomNavigationBar

class ContactState extends State<ContactView> {
@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: CustomAppBar("title"),
      endDrawer: CustomDrawer(),
      bottomNavigationBar: CustomBottombar(),
      body: SafeArea(
          bottom: true,
          child: SingleChildScrollView(
            child: Container(child: Text("Contact"),),
          )),
    );
  }
}

У меня также будет много других представлений, которых нет в массиве элементов но я хочу отобразить BottomNavigationBar. Моя проблема - действительно эта функция.

void _onItemTapped(int index) {
        setState(() {
          selectedIndex = index;
          Navigator.of(context).popUntil((route) => route.isFirst
          );
          Navigator.pushReplacement(
                  context,
                  MaterialPageRoute(builder: (context) => _viewList[index]),
                );
        });
      }

, потому что здесь я удаляю историю навигации, чтобы отобразить представление, которое находится в массиве элементов. Есть ли стандартный способ сделать это, надеюсь, кто-то может помочь.

РЕДАКТИРОВАТЬ: Для пояснения: у меня как 10 экранов. Только 3 из них доступны для навигации через BottomNavigationBar, скажем, первые 3 из 10. Теперь я хочу перейти к Screen4 с Screen1. Панель навигации исчезает на экране4. Я хочу, чтобы панель навигации оставалась на всех экранах.

Изменить 2

@ Ответ Дхавала Канзары мне помог, но у меня возникла новая проблема. У меня есть enddrawer, до исправления он был выше BottomNavigationBar, теперь BottomNavigationBar выше.

enter image description here

но я хочу вот так

enter image description here

1 Ответ

1 голос
/ 04 мая 2020

Используйте CupertinoTabBar, как показано ниже для состояния c BottomNavigationBar.

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:mqttdemo/Screen2.dart';
import 'package:mqttdemo/Screen3.dart';

import 'Screen1.dart';

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  int _currentIndex;
  List<Widget> _children;

  @override
  void initState() {
    _currentIndex = 0;
    _children = [
      Screen1(),
      Screen2(),
      Screen3(),
    ];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return CupertinoTabScaffold(
      tabBar: CupertinoTabBar(
        currentIndex: _currentIndex,
        onTap: onTabTapped,
        items: [
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            title: Text("Screen 1"),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            title: Text("Screen 2"),
          ),
          BottomNavigationBarItem(
              icon: Icon(Icons.home), title: Text("Screen 3")),
        ],

      ),
        tabBuilder: (BuildContext context, int index) {
          return CupertinoTabView(
            builder: (BuildContext context) {
              return SafeArea(
                top: false,
                bottom: false,
                child: CupertinoApp(
                  home: CupertinoPageScaffold(
                    resizeToAvoidBottomInset: false,
                    child: _children[_currentIndex],
                  ),
                ),
              );
            },
          );
        }
    );
  }

  void onTabTapped(int index) {
    setState(() {
      _currentIndex = index;
    });
  }
}

Перейдите к экрану 4 с экрана 3, как показано ниже:

    class Screen3 extends StatefulWidget {
      @override
      _Screen3State createState() => _Screen3State();
    }

    class _Screen3State extends State<Screen3> {
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.black,
          child: Center(
            child: RaisedButton(
              child: Text("Click me"),
              onPressed: () {
                Navigator.of(context, rootNavigator: false).push(MaterialPageRoute(
                    builder: (context) => Screen4(), maintainState: false));
              },
            ),
          ),
        );
      }

}
...