简体   繁体   中英

How to change the shape of Tabs() when TabBarView() is swiped in Flutter?

I have been trying to change the shape of Tabs() in TabBar() and I did it using onTap:(){} property in TabBar() .

But the problem is that I want the same functionality when I swipe the pages in TabBarView() , so I tried doing it too, but I can't.

I want to change the shape of Tabs() when I swipe the pages in TabBarView() .

Below is my code implementation:

import 'package:flutter/material.dart';

class Demo extends StatefulWidget with PreferredSizeWidget {
  @override
  _DemoState createState() => _DemoState();

  @override
  Size get preferredSize => AppBar().preferredSize;
}

class _DemoState extends State<Demo> with SingleTickerProviderStateMixin {
  late TabController _tabController;
  late int _index;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 3, vsync: this, initialIndex: 1);
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    _index = _tabController.index;

    return SafeArea(
      child: Scaffold(
        body: TabBarView(
          controller: _tabController,
          children: [
            Pages(pageName: "Page 0"),
            Pages(pageName: "Page 1"),
            Pages(pageName: "Page 2"),
          ],
        ),
        appBar: AppBar(
          elevation: 0.0,
          bottom: TabBar(
            onTap: (value) {
              setState(() {
                value = _index;
                print("TabIndex: $value");
              });
            },
            labelColor: Colors.black,
            indicator: BoxDecoration(
              color: Colors.white,
              borderRadius: _index == 0
                  ? BorderRadius.only(topRight: Radius.circular(10.0))
                  : _index == 1
                      ? BorderRadius.only(
                          topLeft: Radius.circular(10.0),
                          topRight: Radius.circular(10.0))
                      : BorderRadius.only(topLeft: Radius.circular(10.0)),
            ),
            controller: _tabController,
            tabs: [
              Tab(text: "Tab0"),
              Tab(text: "Tab1"),
              Tab(text: "Tab2"),
            ],
          ),
        ),
      ),
    );
  }
}

class Pages extends StatelessWidget {
  late final String pageName;
  Pages({required this.pageName});
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: Text(
          pageName,
          style: TextStyle(
            color: Colors.black,
            fontWeight: FontWeight.bold,
            fontSize: 60.0,
          ),
        ),
      ),
    );
  }
}

What am I missing here? Can you tell me!!

This confusion can be solved by adding addListners() with the _tabController .

Below is my answer:

I removed the onTap:(){} property from the TabBar() as it was not required and in initState(){} I have added the addListener() method with the _tabController . This solves everything and the Tabs() styling(s) listen to swiping functionality from the TabBarView()

import 'package:flutter/material.dart';

class Demo extends StatefulWidget with PreferredSizeWidget {
  @override
  _DemoState createState() => _DemoState();

  @override
  Size get preferredSize => AppBar().preferredSize;
}

class _DemoState extends State<Demo> with SingleTickerProviderStateMixin {
  late TabController _tabController;
  int _selectedIndex = 1;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 3, vsync: this, initialIndex: 1);

    _tabController.addListener(() {
      setState(() {
        _selectedIndex = _tabController.index;
      });
      print("Current Index: $_selectedIndex");
    });
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: TabBarView(
          controller: _tabController,
          children: [
            Pages(pageName: "Page 0"),
            Pages(pageName: "Page 1"),
            Pages(pageName: "Page 2"),
          ],
        ),
        appBar: AppBar(
          elevation: 0.0,
          bottom: TabBar(
            labelColor: Colors.black,
            indicator: BoxDecoration(
              color: Colors.white,
              borderRadius: _selectedIndex == 0
                  ? BorderRadius.only(topRight: Radius.circular(10.0))
                  : _selectedIndex == 1
                      ? BorderRadius.only(
                          topLeft: Radius.circular(10.0),
                          topRight: Radius.circular(10.0))
                      : BorderRadius.only(topLeft: Radius.circular(10.0)),
            ),
            controller: _tabController,
            tabs: [
              Tab(text: "Tab0"),
              Tab(text: "Tab1"),
              Tab(text: "Tab2"),
            ],
          ),
        ),
      ),
    );
  }
}

class Pages extends StatelessWidget {
  late final String pageName;
  Pages({required this.pageName});
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: Text(
          pageName,
          style: TextStyle(
            color: Colors.black,
            fontWeight: FontWeight.bold,
            fontSize: 60.0,
          ),
        ),
      ),
    );
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM