This commit is contained in:
Junyuan Feng
2022-02-08 21:12:38 +08:00
parent 4636219b6a
commit d70cbb66d2
10 changed files with 187 additions and 64 deletions

View File

@@ -1,13 +1,16 @@
import 'package:after_layout/after_layout.dart';
import 'package:flutter/material.dart';
import 'package:flutter_advanced_drawer/flutter_advanced_drawer.dart';
import 'package:get_it/get_it.dart';
import 'package:toolbox/core/analysis.dart';
import 'package:toolbox/core/build_mode.dart';
import 'package:toolbox/core/route.dart';
import 'package:toolbox/core/update.dart';
import 'package:toolbox/core/utils.dart';
import 'package:toolbox/data/model/app/navigation_item.dart';
import 'package:toolbox/data/provider/server.dart';
import 'package:toolbox/data/res/build_data.dart';
import 'package:toolbox/data/res/color.dart';
import 'package:toolbox/data/res/icon/common.dart';
import 'package:toolbox/data/res/tab.dart';
import 'package:toolbox/data/res/url.dart';
@@ -36,23 +39,26 @@ class _MyHomePageState extends State<MyHomePage>
SingleTickerProviderStateMixin,
AfterLayoutMixin,
WidgetsBindingObserver {
late final TabController _tabController;
late final ServerProvider _serverProvider;
late final PageController _pageController;
late final AdvancedDrawerController _advancedDrawerController;
late int _selectIndex;
late double _width;
@override
void initState() {
super.initState();
_serverProvider = locator<ServerProvider>();
WidgetsBinding.instance?.addObserver(this);
_tabController = TabController(
initialIndex: locator<SettingStore>().launchPage.fetch()!,
length: tabs.length,
vsync: this);
_tabController.addListener(() {
if (_tabController.index == 0) {
FocusScope.of(context).unfocus();
}
});
_selectIndex = locator<SettingStore>().launchPage.fetch()!;
_pageController = PageController(initialPage: _selectIndex);
_advancedDrawerController = AdvancedDrawerController();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
_width = MediaQuery.of(context).size.width;
}
@override
@@ -77,37 +83,123 @@ class _MyHomePageState extends State<MyHomePage>
Widget build(BuildContext context) {
setTransparentNavigationBar(context);
super.build(context);
return Scaffold(
appBar: AppBar(
title: GestureDetector(
onLongPress: () =>
AppRoute(const DebugPage(), 'Debug Page').go(context),
child: const Text(BuildData.name),
),
bottom: TabBar(
indicatorColor: widget.primaryColor,
tabs: tabs.map((e) => Tab(text: e)).toList(),
controller: _tabController,
return AdvancedDrawer(
controller: _advancedDrawerController,
animationCurve: Curves.easeInOutCirc,
animationDuration: const Duration(milliseconds: 300),
animateChildDecoration: true,
rtlOpening: false,
disabledGestures: true,
childDecoration: const BoxDecoration(
// NOTICE: Uncomment if you want to add shadow behind the page.
// Keep in mind that it may cause animation jerks.
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.black12,
blurRadius: 0.0,
),
],
borderRadius: BorderRadius.all(Radius.circular(16)),
),
drawer: _buildDrawer(),
child: Scaffold(
appBar: AppBar(
title: Text(tabItems[_selectIndex].title),
actions: [
IconButton(
icon: const Icon(Icons.developer_mode, size: 23),
tooltip: 'Debug',
onPressed: () =>
AppRoute(const DebugPage(), 'Debug Page').go(context),
),
],
leading: IconButton(
onPressed: () => _advancedDrawerController.showDrawer(),
icon: ValueListenableBuilder<AdvancedDrawerValue>(
valueListenable: _advancedDrawerController,
builder: (_, value, __) {
return AnimatedSwitcher(
duration: const Duration(milliseconds: 250),
child: Icon(
value.visible ? Icons.clear : Icons.menu,
key: ValueKey<bool>(value.visible),
),
);
},
),
),
),
body: PageView(
physics: const ClampingScrollPhysics(),
controller: _pageController,
onPageChanged: (i) {
FocusScope.of(context).unfocus();
_selectIndex = i;
setState(() {});
},
children: const [ServerPage(), ConvertPage(), PingPage()],
),
bottomNavigationBar: _buildBottom(context),
));
}
Widget _buildItem(int idx, NavigationItem item, bool isSelected) {
bool isDarkMode = Theme.of(context).brightness == Brightness.dark;
final width = _width / tabItems.length;
return AnimatedContainer(
duration: const Duration(milliseconds: 377),
curve: Curves.fastOutSlowIn,
height: 50,
width: isSelected ? width : width - 17,
decoration: BoxDecoration(
color: isSelected
? isDarkMode
? Colors.white12
: Colors.black.withOpacity(0.07)
: Colors.transparent,
borderRadius: const BorderRadius.all(Radius.circular(50))),
child: IconButton(
icon: Icon(item.icon),
tooltip: item.title,
splashRadius: width / 3.3,
padding: const EdgeInsets.only(left: 17, right: 17),
onPressed: () {
setState(() {
_pageController.animateToPage(idx,
duration: const Duration(milliseconds: 677),
curve: Curves.fastLinearToSlowEaseIn);
});
},
),
drawer: _buildDrawer(),
body: TabBarView(controller: _tabController, children: [
ServerPage(_tabController),
const ConvertPage(),
const PingPage()
]),
);
}
Widget _buildBottom(BuildContext context) {
return SafeArea(
child: Container(
height: 56,
padding: const EdgeInsets.only(left: 8, top: 4, bottom: 4, right: 8),
width: _width,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: tabItems.map((item) {
int itemIndex = tabItems.indexOf(item);
return _buildItem(itemIndex, item, _selectIndex == itemIndex);
}).toList(),
),
));
}
Widget _buildDrawer() {
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
return SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
UserAccountsDrawerHeader(
accountName: const Text(BuildData.name),
accountEmail: Text(_buildVersionStr()),
currentAccountPicture: _buildIcon(),
_buildIcon(),
const Text(BuildData.name),
Text(_buildVersionStr()),
SizedBox(
height: MediaQuery.of(context).size.height * 0.07,
),
ListTile(
leading: const Icon(Icons.settings),
@@ -149,9 +241,19 @@ class _MyHomePageState extends State<MyHomePage>
}
Widget _buildIcon() {
return ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 60, maxWidth: 60),
child: appIcon,
return Stack(
alignment: Alignment.center,
children: [
ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 53, maxWidth: 53),
child: Container(
color: primaryColor,
)),
ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 83, maxWidth: 83),
child: appIcon,
)
],
);
}