forked from lxm_flutter/FlutterUnit
优化顶部 topbar
This commit is contained in:
@@ -54,10 +54,10 @@ android {
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
// keyAlias keystoreProperties['keyAlias']
|
||||
// keyPassword keystoreProperties['keyPassword']
|
||||
// storeFile file(keystoreProperties['storeFile'])
|
||||
// storePassword keystoreProperties['storePassword']
|
||||
keyAlias keystoreProperties['keyAlias']
|
||||
keyPassword keystoreProperties['keyPassword']
|
||||
storeFile file(keystoreProperties['storeFile'])
|
||||
storePassword keystoreProperties['storePassword']
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#storePassword=toly1994
|
||||
#keyPassword=toly1994328
|
||||
#keyAlias= king
|
||||
#storeFile=/Users/mac/Coder/files/key/toly1994.jks
|
||||
storePassword=toly1994
|
||||
keyPassword=toly1994328
|
||||
keyAlias= king
|
||||
storeFile=/Users/mac/Coder/files/key/toly1994.jks
|
||||
@@ -35,8 +35,7 @@ class FeedbackWidget extends StatefulWidget {
|
||||
_FeedBackState createState() => _FeedBackState();
|
||||
}
|
||||
|
||||
class _FeedBackState extends State<FeedbackWidget>
|
||||
with SingleTickerProviderStateMixin {
|
||||
class _FeedBackState extends State<FeedbackWidget> with SingleTickerProviderStateMixin {
|
||||
AnimationController _controller;
|
||||
|
||||
@override
|
||||
|
||||
@@ -5,8 +5,13 @@ import 'package:flutter/material.dart';
|
||||
/// 说明:
|
||||
|
||||
class NoMoreWidget extends StatelessWidget {
|
||||
|
||||
const NoMoreWidget();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(height: 56);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -2,11 +2,11 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_unit/app/router/unit_router.dart';
|
||||
import 'package:flutter_unit/blocs/bloc_exp.dart';
|
||||
import 'package:flutter_unit/painter_system/gallery_unit.dart';
|
||||
import 'package:flutter_unit/views/components/project/nav/unit_bottom_bar.dart';
|
||||
import 'package:flutter_unit/views/components/project/overlay_tool_wrapper.dart';
|
||||
import 'package:flutter_unit/views/pages/category/collect_page.dart';
|
||||
import 'package:flutter_unit/views/pages/category/home_right_drawer.dart';
|
||||
import 'package:flutter_unit/painter_system/gallery_unit.dart';
|
||||
import 'package:flutter_unit/views/pages/user/user_page.dart';
|
||||
import 'package:flutter_unit/views/pages/widget_home/home_drawer.dart';
|
||||
import 'package:flutter_unit/views/pages/widget_home/home_page.dart';
|
||||
@@ -45,17 +45,18 @@ class _UnitNavigationState extends State<UnitNavigation> {
|
||||
floatingActionButton: _buildSearchButton(context),
|
||||
body: wrapOverlayTool(
|
||||
child: PageView(
|
||||
physics: neverScroll,
|
||||
controller: _controller,
|
||||
children: <Widget>[
|
||||
HomePage(),
|
||||
GalleryUnit(),
|
||||
CollectPage(),
|
||||
UserPage(),
|
||||
],
|
||||
),
|
||||
physics: neverScroll,
|
||||
controller: _controller,
|
||||
children: <Widget>[
|
||||
HomePage(),
|
||||
GalleryUnit(),
|
||||
CollectPage(),
|
||||
UserPage(),
|
||||
],
|
||||
),
|
||||
bottomNavigationBar: _buildBottomNav(context));
|
||||
),
|
||||
bottomNavigationBar: _buildBottomNav(context),
|
||||
);
|
||||
}
|
||||
|
||||
// 构建悬浮按钮工具
|
||||
|
||||
@@ -48,7 +48,7 @@ class _HomePageState extends State<HomePage>
|
||||
slivers: <Widget>[
|
||||
_buildPersistentHeader(),
|
||||
_buildContent(state),
|
||||
SliverToBoxAdapter(
|
||||
const SliverToBoxAdapter(
|
||||
child: NoMoreWidget(),
|
||||
)
|
||||
],
|
||||
|
||||
@@ -14,7 +14,7 @@ class TolyAppBar extends StatefulWidget {
|
||||
TolyAppBar({this.maxHeight, this.onItemClick, this.defaultIndex = 0});
|
||||
}
|
||||
|
||||
const _kBorderRadius = BorderRadius.only(
|
||||
const BorderRadius _kBorderRadius = BorderRadius.only(
|
||||
bottomLeft: Radius.circular(15),
|
||||
bottomRight: Radius.circular(15),
|
||||
);
|
||||
@@ -27,6 +27,7 @@ class _TolyAppBarState extends State<TolyAppBar>
|
||||
with SingleTickerProviderStateMixin {
|
||||
double _width = 0;
|
||||
int _selectIndex = 0;
|
||||
int _prevSelectIndex = 0;
|
||||
|
||||
static const List<int> colors = [
|
||||
0xff44D1FD,
|
||||
@@ -48,50 +49,59 @@ class _TolyAppBarState extends State<TolyAppBar>
|
||||
'Other'
|
||||
];
|
||||
|
||||
|
||||
AnimationController _controller;
|
||||
Animation<double> circleAnim;
|
||||
Animation<double> heightAnim;
|
||||
Animation<double> backCircleAnim;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = AnimationController(
|
||||
duration: const Duration(milliseconds: 300), vsync: this)
|
||||
..addListener(_render)
|
||||
..addStatusListener(_listenStatus);
|
||||
value: 1,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
vsync: this,
|
||||
);
|
||||
circleAnim = circleTween.animate(_controller);
|
||||
heightAnim = CurveTween(curve: Curves.ease).animate(_controller);
|
||||
backCircleAnim = ReverseAnimation(circleAnim);
|
||||
_selectIndex = widget.defaultIndex;
|
||||
}
|
||||
|
||||
void _render() {
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
void _listenStatus(AnimationStatus status) {
|
||||
if (status == AnimationStatus.completed) {
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
int get nextIndex => (_selectIndex + 1) % colors.length;
|
||||
|
||||
bool clicked = false;
|
||||
Tween<double> circleTween = Tween(begin: 1, end: 0);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_width = MediaQuery.of(context).size.width / colors.length;
|
||||
return Container(
|
||||
alignment: Alignment.center,
|
||||
child: Flow(
|
||||
return Center(
|
||||
child:Flow(
|
||||
delegate: TolyAppBarDelegate(
|
||||
_selectIndex, clicked ? _controller.value : 1, widget.maxHeight),
|
||||
_selectIndex,
|
||||
_prevSelectIndex,
|
||||
widget.maxHeight,
|
||||
repaint: heightAnim,
|
||||
),
|
||||
children: [
|
||||
...colors
|
||||
.map((e) => GestureDetector(
|
||||
onTap: () => _onTap(e), child: _buildChild(e)))
|
||||
onTap: () => _onTap(e),
|
||||
child: _buildChild(e),
|
||||
))
|
||||
.toList(),
|
||||
...colors.map((e) => Circle(
|
||||
color: Color(e),
|
||||
radius: 6,
|
||||
))
|
||||
...colors.map((e) {
|
||||
Widget child = Circle(
|
||||
color: Color(e),
|
||||
radius: 6,
|
||||
);
|
||||
if (e == colors[_selectIndex]) {
|
||||
return ScaleTransition(scale: circleAnim, child: child);
|
||||
}
|
||||
if (e == colors[_prevSelectIndex]) {
|
||||
return ScaleTransition(scale: backCircleAnim, child: child);
|
||||
}
|
||||
return child;
|
||||
})
|
||||
]),
|
||||
);
|
||||
}
|
||||
@@ -116,13 +126,12 @@ class _TolyAppBarState extends State<TolyAppBar>
|
||||
|
||||
void _onTap(int color) {
|
||||
if (_selectIndex == colors.indexOf(color)) return;
|
||||
clicked = true;
|
||||
setState(() {
|
||||
_controller.reset();
|
||||
_controller.forward();
|
||||
_prevSelectIndex = _selectIndex;
|
||||
_selectIndex = colors.indexOf(color);
|
||||
if (widget.onItemClick != null)
|
||||
widget.onItemClick(_selectIndex);
|
||||
if (widget.onItemClick != null) widget.onItemClick(_selectIndex);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -135,10 +144,15 @@ class _TolyAppBarState extends State<TolyAppBar>
|
||||
|
||||
class TolyAppBarDelegate extends FlowDelegate {
|
||||
final int selectIndex;
|
||||
final double factor;
|
||||
final int prevSelectIndex;
|
||||
final double height;
|
||||
final Animation<double> repaint;
|
||||
|
||||
TolyAppBarDelegate(this.selectIndex, this.factor, this.height);
|
||||
TolyAppBarDelegate(this.selectIndex, this.prevSelectIndex, this.height,
|
||||
{this.repaint})
|
||||
: super(repaint: repaint);
|
||||
|
||||
double get factor => repaint.value;
|
||||
|
||||
@override
|
||||
void paintChildren(FlowPaintingContext context) {
|
||||
@@ -151,6 +165,11 @@ class TolyAppBarDelegate extends FlowDelegate {
|
||||
context.paintChild(i,
|
||||
transform: Matrix4.translationValues(ox, 20.0 * factor - 20, 0.0));
|
||||
ox += cSize.width;
|
||||
} else if (i == prevSelectIndex) {
|
||||
context.paintChild(i,
|
||||
transform:
|
||||
Matrix4.translationValues(ox, 20.0 * (1 - factor) - 20, 0.0));
|
||||
ox += cSize.width;
|
||||
} else {
|
||||
context.paintChild(i,
|
||||
transform: Matrix4.translationValues(ox, -20, 0.0));
|
||||
@@ -158,18 +177,18 @@ class TolyAppBarDelegate extends FlowDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制小点
|
||||
for (int i = (context.childCount / 2).floor(); i < context.childCount; i++) {
|
||||
if (i - (context.childCount / 2).floor() == selectIndex) {
|
||||
obx += context.getChildSize(0).width;
|
||||
} else {
|
||||
context.paintChild(i,
|
||||
transform: Matrix4.translationValues(
|
||||
obx + context.getChildSize(0).width / 2 - 5, height + 5, 0));
|
||||
obx += context.getChildSize(0).width;
|
||||
}
|
||||
context.paintChild(i,
|
||||
transform: Matrix4.translationValues(
|
||||
obx + context.getChildSize(0).width / 2 - 5, height + 5, 0));
|
||||
obx += context.getChildSize(0).width;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(FlowDelegate oldDelegate) => true;
|
||||
bool shouldRepaint(TolyAppBarDelegate oldDelegate) =>
|
||||
oldDelegate.selectIndex != selectIndex ||
|
||||
oldDelegate.height != height ||
|
||||
oldDelegate.repaint != repaint;
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
/Volumes/coder/SDK/st_flutter/flutter/.pub-cache/hosted/pub.flutter-io.cn/path_provider_linux-0.0.1+2/
|
||||
@@ -1,7 +1,7 @@
|
||||
name: flutter_unit
|
||||
description: A new Flutter application.
|
||||
|
||||
version: 1.5.2
|
||||
version: 1.5.3
|
||||
author: 张风捷特烈 <1981462002@qq.com>
|
||||
homepage: https://juejin.cn/user/149189281194766/posts
|
||||
|
||||
|
||||
Reference in New Issue
Block a user