简体   繁体   中英

Flutter how to create clickable tabs

How to create basic design like from sketch from image. First container with list of tabs is static, and containers above it is dynamic, and contain text - Text for tab 1 if tab 1 is clicked, or Text for tab 2 if tab 2 is clicked. Also text for Tab1 or Tab2 must be underline if we click on it.

Something like this: 在此处输入图片说明

I'm not sure I understand you completely.
But if you want to implement a TabBar, you can use flutter TabBar() documented here: https://flutter.dev/docs/cookbook/design/tabs

Or there is a package you can use: https://pub.dev/packages/tabbar

Using a GestureDetector widget to tell when a user taps on the tabs and then updating the state with setState is maybe the most simple way of doing this.

Here is a very basic example of using a stateful widget and setState to update the page. You can approach this problem with any state management strategy, though.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Scaffold(body: MyHomePage()),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String selectedTab;
  static const String TAB_1 = 'Tab 1';
  static const String TAB_2 = 'Tab 2';

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Expanded(
          flex: 1,
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.end,
            children: [
              GestureDetector(
                onTap: () {
                  setState(() => selectedTab = TAB_1);
                },
                child: Container(
                  padding: const EdgeInsets.all(12.0),
                  child: Text(TAB_1),
                  decoration: selectedTab == TAB_1
                      ? BoxDecoration(border: Border(bottom: BorderSide()))
                      : null,
                ),
              ),
              GestureDetector(
                onTap: () {
                  setState(() => selectedTab = TAB_2);
                },
                child: Container(
                  padding: const EdgeInsets.all(12.0),
                  child: Text(TAB_2),
                  decoration: selectedTab == TAB_2
                      ? BoxDecoration(border: Border(bottom: BorderSide()))
                      : null,
                ),
              )
            ],
          ),
        ),
        Container(height: 20.0),
        Expanded(
          flex: 2,
          child: Container(
            decoration: BoxDecoration(
                border: Border.all(width: 5),
                borderRadius: BorderRadius.circular(12.0)),
            child: Center(child: Text(textForTab(selectedTab))),
          ),
        )
      ],
    );
  }

  String textForTab(String tabId) {
    switch (tabId) {
      case TAB_1:
        return 'Text for Tab 1';
      case TAB_2:
        return 'Text for Tab 2';
      default:
        return 'Select Tab';
    }
  }
}

You can do it using TabBar widget.

class CustomTabBar extends StatefulWidget {
 @override
 _CustomTabBarState createState() => _CustomTabBarState();
}

class _CustomTabBarState extends State<CustomTabBar>
  with SingleTickerProviderStateMixin {
  TabController _tabController;

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

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

  @override
  Widget build(BuildContext context) {
   return Scaffold(
    appBar: AppBar(
     title: Text(
      'Tab Demo',
     ),
    ),
    body: 
     Column(
      children: [
        Container(
          height: 45,
          child: TabBar(
            controller: _tabController,
            indicator: BoxDecoration(
              border: Border(bottom: BorderSide(color: Colors.blue,width: 2,style: 
              BorderStyle.solid)),
            ),
            labelColor: Colors.blue,
            unselectedLabelColor: Colors.black,
            tabs: [
              // first tab
              Tab(
                text: 'Home',
              ),

              // second tab
              Tab(
                text: 'Profile',
              ),
            ],
          ),
        ),
        // tab bar view
        Expanded(
          child: TabBarView(
            controller: _tabController,
            children: [
              // first tab widget 
              Center(
                child: Text(
                  'Home',
                  style: TextStyle(
                    fontSize: 26,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),

              // Second tab widget
              Center(
                child: Text(
                  'Profile',
                  style: TextStyle(
                    fontSize: 26,
                    fontWeight: FontWeight.bold,
                  ),
                ),
              ),
            ],
          ),
        ),
      ],
    ),
  );
  }
}

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