tsacdop-podcast-app-android/lib/podcasts/custom_tabview.dart

147 lines
4.2 KiB
Dart

import 'package:flutter/material.dart';
class CustomTabView extends StatefulWidget {
final int itemCount;
final IndexedWidgetBuilder tabBuilder;
final IndexedWidgetBuilder pageBuilder;
final ValueChanged<int?>? onPositionChange;
final ValueChanged<double>? onScroll;
final int? initPosition;
CustomTabView({
required this.itemCount,
required this.tabBuilder,
required this.pageBuilder,
this.onPositionChange,
this.onScroll,
this.initPosition,
});
@override
_CustomTabsState createState() => _CustomTabsState();
}
class _CustomTabsState extends State<CustomTabView>
with TickerProviderStateMixin {
TabController? controller;
int? _currentCount;
int? _currentPosition;
@override
void initState() {
_currentPosition = widget.initPosition ?? 0;
controller = TabController(
length: widget.itemCount,
vsync: this,
initialIndex: _currentPosition!,
);
controller!.addListener(onPositionChange);
controller!.animation!.addListener(onScroll);
_currentCount = widget.itemCount;
super.initState();
}
@override
void didUpdateWidget(CustomTabView oldWidget) {
if (_currentCount != widget.itemCount) {
controller!.animation!.removeListener(onScroll);
controller!.removeListener(onPositionChange);
controller!.dispose();
if (widget.initPosition != null) {
_currentPosition = widget.initPosition;
}
if (_currentPosition! > widget.itemCount - 1) {
_currentPosition = widget.itemCount - 1;
_currentPosition = _currentPosition! < 0 ? 0 : _currentPosition;
if (widget.onPositionChange is ValueChanged<int>) {
WidgetsBinding.instance!.addPostFrameCallback((_) {
if (mounted) {
widget.onPositionChange!(_currentPosition);
}
});
}
}
_currentCount = widget.itemCount;
setState(() {
controller = TabController(
length: widget.itemCount,
vsync: this,
initialIndex: _currentPosition!,
);
controller!.addListener(onPositionChange);
controller!.animation!.addListener(onScroll);
});
} else if (widget.initPosition != null) {
controller!.animateTo(widget.initPosition!);
}
super.didUpdateWidget(oldWidget);
}
@override
void dispose() {
controller!.animation!.removeListener(onScroll);
controller!.removeListener(onPositionChange);
controller!.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
height: 50.0,
padding: EdgeInsets.all(10.0),
child: TabBar(
indicatorSize: TabBarIndicatorSize.label,
labelPadding: EdgeInsets.symmetric(horizontal: 5.0),
indicatorPadding: EdgeInsets.symmetric(horizontal: 5.0),
isScrollable: true,
controller: controller,
labelColor: Colors.white,
unselectedLabelColor: Colors.grey[700],
indicator: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(15)),
color: Theme.of(context).accentColor,
),
tabs: List.generate(
widget.itemCount,
(index) => widget.tabBuilder(context, index),
),
),
),
Expanded(
child: TabBarView(
controller: controller,
children: List.generate(
widget.itemCount,
(index) => widget.pageBuilder(context, index),
),
),
),
],
);
}
onPositionChange() {
if (!controller!.indexIsChanging) {
_currentPosition = controller!.index;
if (widget.onPositionChange is ValueChanged<int>) {
widget.onPositionChange!(_currentPosition);
}
}
}
onScroll() {
if (widget.onScroll is ValueChanged<double>) {
widget.onScroll!(controller!.animation!.value);
}
}
}