preface

Before, I made a flutter application that imitatedgold digging, and the code has been put on Guthub. Due to some personal problems, THERE has been no update on flutter related articles for a long time. This article will introduce how to build Tabbar, so that tabbar can be used to slide the screen

To build tabbar’s sliding screen cutting, the following are the main points:

  • Configuration of entry files
  • An overall construction of a page
    • On: Title bar component
    • Middle: page jump, slide render middle part of the page
    • Next: Tabbar rendering and related interaction logic

Configuration of entry files

The main dart files

This file does some initialization of the data, the cache, and where does the page jump to when the page starts

Some apps also need to determine if the user is logged in and redirect to the login page, which is a blog site and removes some of the logic for jumping in.

import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_application/config/storage_manager.dart'; import 'package:flutter_application/config/theme.dart'; import 'package:flutter_application/root/root_page.dart'; import 'package:flutter_application/route/route.dart'; import 'mine.dart'; void main() async{ FlutterError.onError = (FlutterErrorDetails details) { FlutterError.dumpErrorToConsole(details); if (kReleaseMode) exit(1); }; / / make sure initialization WidgetsFlutterBinding. The ensureInitialized (); // Cache initializes await storagemanager.init (); runApp(MyApp()); } class MyApp extends StatelessWidget {@override Widget build(BuildContext context) { NavigatorKey: navGk, title: 'Flutter Blog Exercise ', theme: ThemeData(scaffoldBackgroundColor: bgColor, hintColor: Colors. Grey. WithOpacity (0.3), splashColor: Colors, transparent, canvasColor: Colors.transparent ), debugShowCheckedModeBanner: false, routes: { '/': (context) { return RootPage(); }}); }}Copy the code

The overall build of the page

Generally, the TAB page is divided into the following three parts

  • On: Title bar component
  • Middle: page jump, slide render middle part of the page
  • Next: Tabbar rendering and related interaction logic

Title bar component

common_bar.dart

This component is mainly configured with the title, interactive ICONS, theme colors and some related styles

Interactive logic in the main implementation of the click interaction effect

import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_application/config/theme.dart'; class CommonBar extends StatelessWidget implements PreferredSizeWidget { final String title; final bool showShadow; final List<Widget>? rightDMActions; final Color backgroundColor; final Color mainColor; final Widget? titleW; final Widget? leadingW; final PreferredSizeWidget? bottom; final String leadingImg; CommonBar( {this.title = '', this.showShadow = false, this.rightDMActions, this.backgroundColor = appBarColor, this.mainColor = Colors.white, this.titleW, this.leadingW, this.bottom, this.leadingImg = ''}); // tabBar left icon and related operation logic Widget? leading(BuildContext context) { bool isShow = Navigator.canPop(context); if (isShow) { return new InkWell( child: new Container( width: 15, height: 28, child: leadingImg ! = ' '? new Image.asset(leadingImg) : new Icon(CupertinoIcons.back, color: mainColor), ), onTap: () { if (Navigator.canPop(context)) { FocusScope.of(context).requestFocus(new FocusNode()); Navigator.pop(context); }}); } else { return null; }} @override Widget build(BuildContext context) {// Build Widget appBar = new appBar (title: titleW! = null ? TitleW: new Text(title, style: new TextStyle(color: mainColor, fontSize: 16.0, fontWeight: FontWeight.w600, ), ), backgroundColor: backgroundColor, elevation: 0, brightness: Brightness.light, leading: leadingW ?? leading(context), centerTitle: true, actions: rightDMActions ?? [new Center()], bottom: bottom ?? null, ); return showShadow ? new Container( decoration: BoxDecoration( border: Border( bottom: new BorderSide(color: Colors.grey, width: 5))), child: appBar,) : appBar; } @override // TODO: implement preferredSize Size get preferredSize => new Size(100, 50); }Copy the code

Page jump and slide effect

root_tabbar.dart

Swiping is mainly to determine whether the application environment is Android or IOS

ClampingScrollPhysics()

IOS sliding method: NeverScrollableScrollPhysics ()

Then switch the related pages of the related tabbarModel array based on the index value

import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_application/config/theme.dart'; import 'package:flutter_application/pages/common/bar/common_bar.dart'; class RootTabBar extends StatefulWidget { final List pages; final int currentIndex; RootTabBar({required this.pages, this.currentIndex = 0}); State<StatefulWidget> createState() => new RootTabBarState(); } class RootTabBarState extends State<RootTabBar> { List<BottomNavigationBarItem> pages = []; late int currentIndex; late PageController pageController; @override void initState() { super.initState(); currentIndex = widget.currentIndex; pageController = PageController(initialPage: currentIndex); widget.pages.forEach((element) { TabBarModel model = element; pages.add(new BottomNavigationBarItem( icon: model.icon, activeIcon: model.selectIcon, title: new Text( model.title! , style: new TextStyle(fontSize: 12.0),)); }); } @override Widget build(BuildContext context) { // if(pageController) { pageController = PageController(initialPage: currentIndex); // } final BottomNavigationBar bottomNavigationBar = new BottomNavigationBar( items: pages, type: BottomNavigationBarType.fixed, currentIndex: currentIndex, onTap: (int index) { setState(() { currentIndex = index; pageController.jumpToPage(currentIndex); }); }, unselectedFontSize: 12.0, selectedFontSize: 12.0, selectedItemColor: primaryColor, elevation: 0,); var appBar = new CommonBar( title: widget.pages[currentIndex].title, showShadow: false); Return Scaffold (resizeToAvoidBottomInset: false, / / extrusion problems caused by the key up / / bottomNavigationBar TAB at the bottom of the column: new Theme (data: new ThemeData( canvasColor: Colors.grey[50], highlightColor: Colors.transparent, splashColor: Colors.transparent), child: new Container( decoration: BoxDecoration( border: Border(top: BorderSide(color: LineColor, width: 0.2)), child: bottomationbar,)), new PageView.builder( itemBuilder: (BuildContext context, int index) => widget.pages[index].page, controller: pageController, itemCount: pages.length, physics: Platform.isAndroid ? new ClampingScrollPhysics() : new NeverScrollableScrollPhysics(), onPageChanged: (int index) => setState(() => currentIndex = index), ), ); } } class TabBarModel { final String? title; final Widget icon; final Widget? selectIcon; final Widget? page; TabBarModel({this.title, required this.icon, this.selectIcon, this.page}); }Copy the code

Tabbar related page configuration

root_page.dart

import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_application/config/theme.dart'; import 'package:flutter_application/pages/tabbar/Index.dart'; import 'package:flutter_application/pages/tabbar/mine.dart'; import 'package:flutter_application/pages/tabbar/boil.dart'; import 'package:flutter_application/root/root_tabbar.dart'; import 'package:flutter_application/route/route.dart'; class RootPage extends StatefulWidget { _RootPageState createState() => _RootPageState(); } class _RootPageState extends State<RootPage> { @override Widget build(BuildContext context) { List<TabBarModel> pages = <TabBarModel>[new TabBarModel(title: "家 ", icon: const icon (IconData(0xe7c0,fontFamily: 'MyIcons')), selectIcon: const Icon(IconData(0xe7c0,fontFamily: 'MyIcons'),color: primaryColor,), page: New IndexPage()), // new TabBarModel(// title: 'boiling ', // icon: new LoadImage("assets/images/tab_order_normal_icon.png"), // selectIcon: // new LoadImage("assets/images/tab_order_selected_icon.png"), // page: new BoilPage()), new TabBarModel( title: 'Find ', icon: const icon (IconData(0xe8d6,fontFamily: 'MyIcons')), selectIcon:const Icon(IconData(0xe8d6,fontFamily: 'MyIcons') 'MyIcons'),color: primaryColor,), page: new BoilPage()), // new TabBarModel(// title: 'small book ', // icon: new LoadImage("assets/images/tab_order_normal_icon.png"), // selectIcon: // new LoadImage("assets/images/tab_order_selected_icon.png"), // page: new BoilPage()), new TabBarModel( title: 'My ', icon: const icon (IconData(0xe613,fontFamily: 'MyIcons')), selectIcon:const Icon(IconData(0xe613,fontFamily: 'MyIcons')), 'MyIcons'),color: primaryColor,), page: new MinePage()) ]; return new Scaffold( key: scaffoldGK, body: new RootTabBar(pages: pages, currentIndex: 0), ); } } class LoadImage extends StatelessWidget { final String img; LoadImage(this.img); @override Widget build(BuildContext context) {return new Container(margin: EdgeInsets. Only (bottom: 2.0), child: new Image.asset(img, fit: BoxFit.cover, gaplessPlayback: true), ); }}Copy the code

Slide screen cutting effect