flutter 自定义TabBar
Posted ajanuw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了flutter 自定义TabBar相关的知识,希望对你有一定的参考价值。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:rxdart/subjects.dart';
double ourMap(v, start1, stop1, start2, stop2)
return (v - start1) / (stop1 - start1) * (stop2 - start2) + start2;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return MaterialApp(
home: HomePage(),
);
class HomePage extends StatefulWidget
@override
_HomePageState createState() => _HomePageState();
class _HomePageState extends State<HomePage>
with SingleTickerProviderStateMixin
final int initPage = 0;
PageController _pageController;
List<String> tabs = ['aaa', 'bbb', 'ccc', 'ddd', 'eee'];
Stream<int> get currentPage$ => _currentPageSubject.stream;
Sink<int> get currentPageSink => _currentPageSubject.sink;
BehaviorSubject<int> _currentPageSubject;
Alignment _dragAlignment;
AnimationController _controller;
Animation<Alignment> _animation;
@override
void initState()
super.initState();
_currentPageSubject = BehaviorSubject<int>.seeded(initPage);
_pageController = PageController(initialPage: initPage);
_dragAlignment = Alignment(ourMap(initPage, 0, tabs.length - 1, -1, 1), 0);
_controller = AnimationController(
vsync: this,
duration: kThemeAnimationDuration,
)..addListener(()
setState(()
_dragAlignment = _animation.value;
);
);
currentPage$.listen((int page)
_runAnimation(
_dragAlignment,
Alignment(ourMap(page, 0, tabs.length - 1, -1, 1), 0),
);
);
@override
void dispose()
_currentPageSubject.close();
_pageController.dispose();
_controller.dispose();
super.dispose();
void _runAnimation(Alignment oldA, Alignment newA)
_animation = _controller.drive(
AlignmentTween(
begin: oldA,
end: newA,
),
);
_controller.reset();
_controller.forward();
@override
Widget build(BuildContext context)
return Scaffold(
body: Column(
children: <Widget>[
SizedBox(height: MediaQuery.of(context).padding.top + 20),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Container(
height: 40,
decoration: BoxDecoration(
color: Colors.black38,
borderRadius: BorderRadius.circular(35),
),
child: Stack(
children: <Widget>[
// use animation controller
// Align(
// alignment: _dragAlignment,
// child: LayoutBuilder(
// builder:
// (BuildContext context, BoxConstraints constraints)
// double width = constraints.maxWidth;
// return Padding(
// padding: const EdgeInsets.all(2.0),
// child: Container(
// height: double.infinity,
// width: width / tabs.length,
// decoration: BoxDecoration(
// color: Colors.white,
// borderRadius: BorderRadius.circular(35),
// ),
// ),
// );
// ,
// ),
// ),
// use animated widget
StreamBuilder(
stream: currentPage$,
builder: (context, AsyncSnapshot<int> snapshot)
if (snapshot.connectionState == ConnectionState.active)
return AnimatedAlign(
duration: kThemeAnimationDuration,
alignment: Alignment(
ourMap(snapshot.data, 0, tabs.length - 1, -1, 1),
0),
child: LayoutBuilder(
builder: (BuildContext context,
BoxConstraints constraints)
double width = constraints.maxWidth;
return Padding(
padding: const EdgeInsets.all(2.0),
child: Container(
height: double.infinity,
width: width / tabs.length,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(35),
),
),
);
,
),
);
return SizedBox();
,
),
Align(
alignment: Alignment.center,
child: Row(
children: tabs.map((t)
int index = tabs.indexOf(t);
return Expanded(
child: MaterialButton(
splashColor: Colors.transparent,
focusColor: Colors.transparent,
color: Colors.transparent,
highlightColor: Colors.transparent,
hoverColor: Colors.transparent,
focusElevation: 0.0,
hoverElevation: 0.0,
elevation: 0.0,
highlightElevation: 0.0,
child: StreamBuilder(
stream: currentPage$,
builder:
(context, AsyncSnapshot<int> snapshot)
return AnimatedDefaultTextStyle(
duration: kThemeAnimationDuration,
style: TextStyle(
inherit: true,
color: snapshot.data == index
? Colors.black
: Colors.white,
),
child: Text(t),
);
),
onPressed: ()
currentPageSink.add(index);
_pageController.jumpToPage(index);
,
),
);
).toList(),
),
),
],
),
),
),
Expanded(
child: PageView(
controller: _pageController,
onPageChanged: (page) => currentPageSink.add(page),
children: <Widget>[
for (var t in tabs)
Center(
child: Text(t),
)
],
),
),
],
),
);
以上是关于flutter 自定义TabBar的主要内容,如果未能解决你的问题,请参考以下文章
Flutter AppBar基本用法、TabBar基本用法、自定义TabBar
iOS 自定义TabBarController zhuanzai