android 按钮的Flutter变更GNav选项卡

f45qwnt8  于 2023-02-10  发布在  Android
关注(0)|答案(2)|浏览(107)

我有4个页面在GNav()底部导航栏,我想通过点击一个按钮导航到不同的页面。我知道,可能有类似的问题stackoverflow已经,但我无法实现他们中的任何一个成功,这就是为什么我在这里张贴作为我的"最后的努力"。
首先,我的类RootPage(),这是我定义我的GNav栏和链接到每个选项卡的页面的地方。

import 'package:anitan/pages/menu_bar_pages/profile_page.dart';
import 'package:anitan/pages/menu_bar_pages/search_page.dart';
import 'package:anitan/pages/menu_bar_pages/settings_pages/settings_page.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:google_nav_bar/google_nav_bar.dart';
import 'home_page.dart';

class RootPage extends StatefulWidget {
  RootPage({super.key});

  @override
  State<RootPage> createState() => _RootPageState();
}

class _RootPageState extends State<RootPage>{
  int currentPage = 0;

  List<Widget> pages = const [
    HomePage(),
    ProfilePage(),
    SearchPage(),
    SettingsPage()
  ];

  final user = FirebaseAuth.instance.currentUser!;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
          body: pages[currentPage],
          bottomNavigationBar: Container(
            color: Colors.green,
            child: Padding(
              padding:
                  const EdgeInsets.symmetric(horizontal: 15.0, vertical: 15),
              child: GNav(
                backgroundColor: Colors.green,
                color: Colors.white,
                activeColor: Colors.white,
                tabBackgroundColor: Colors.green.shade800,
                gap: 8,
                onTabChange: (index) => setState(() => currentPage = index),
                selectedIndex: currentPage,
                padding: const EdgeInsets.all(16),
                tabs: const [
                  GButton(icon: Icons.home, text: "Home"),
                  GButton(icon: Icons.person, text: "My Page"),
                  GButton(icon: Icons.search, text: "Browse"),
                  GButton(icon: Icons.settings, text: "Settings"),
                ],
              ),
            ),
          ),
    );
  }
}

接下来,主页有一个按钮。当点击,我想改变我的导航栏所选的标签。推动网页等将导致导航栏消失,这就是为什么这不是一个选项。

import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  const HomePage({super.key,});
 

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: const Text("Home Page"),
        automaticallyImplyLeading: false,
        leading: IconButton(
          onPressed: () {
            Navigator.of(context).pop();
          },
          icon: const Icon(Icons.arrow_back_ios),
        ),
        actions: [
          IconButton(
            onPressed: () {
              debugPrint("appBar Button");
            },
            icon: const Icon(Icons.info_outline),
          ),
        ],
      ),
      body: SafeArea(
        child: ElevatedButton(onPressed: (() => print("Change Page Here")), child: Text("Change-Page")),
      ),
    );
  }
}

我尝试了一些事情,如实现一个StreamController或使用GlobalKey。但我想使用GNav栏,而不是使用Tab控制器,因为它的设计。
从理论上讲,我想做的似乎很简单:我想将currentPage设置为一个新的索引,并调用setState()来显示更改。
任何人都可以帮助我了解我如何可以访问更改索引和更新我的根页面中所选的页面?我花了2天的时间寻找各种解决方案,但我不能让他们中的任何一个工作。
非常感谢!
编辑:请在下面找到我的main. dart的代码。

import 'package:anitan/pages/menu_bar_pages/root_page.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
//import 'firebase_options.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        theme: ThemeData(primarySwatch: Colors.green),
        home: RootPage(),
        );
  }
}
olqngx59

olqngx591#

HomePage已经是RootPage的一部分,需要在同一条路由上,可以使用回调方法处理点击事件/换页。

class HomePage extends StatefulWidget {
  final VoidCallback onTap;
  const HomePage({
    super.key,
    required this.onTap,
  });

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child:
            ElevatedButton(onPressed: widget.onTap, child: Text("Change-Page")),
      ),
    );
  }
}

现在,您将在创建HomePage时获得一个回调方法

int currentPage = 0;

  List<Widget> pages = [
    HomePage(onTap:(){  
       // page 
    } ),

  ];
brccelvz

brccelvz2#

鉴于Yeasin Sheikh的回复,我实施了一个小的变通方案,似乎工作得很好:
首先,按照Yeasin的建议,我在HomePage类中添加了一个VoidCallback函数onTap:

class HomePage extends StatefulWidget {
  final VoidCallback onTap;
  const HomePage({super.key, required this.onTap});

  @override
  State<HomePage> createState() => _HomePageState();
}

然后我调用onTap函数,点击按钮:

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child:
            ElevatedButton(onPressed: widget.onTap(), child: Text("Change-Page")),
      ),
    );
  }
}

在我的rootPage类中,我创建了我的HomePage。当调用该页面的onTap函数时,我调用一个方法来刷新页面(setState),并将currentPage索引作为其中的一部分进行更改。这需要我使用“late”初始化我的页面列表。

class _RootPageState extends State<RootPage>{
  int currentPage = 0;

  late List<Widget> pages = [
    HomePage(onTap:(){  
      _changePage(2);
    } ),
    const ProfilePage(),
    const SearchPage(),
    const SettingsPage()
  ];

  _changePage(int id){
    setState(() {
      currentPage = id;
    });
  }

为了保持所有内容的集中化,我转而使用相同的方法来更新GNav栏的onTabChange部分中的索引。

onTabChange: (index) => setState(() => _changePage(index)),

现在点击按钮切换页面。底部导航栏(GNav)将停留在屏幕上,可以像往常一样使用。
谢谢你的支持,在搞清楚这一点!

相关问题