186 lines
5.3 KiB
Dart
186 lines
5.3 KiB
Dart
import 'package:chat/configs/app_colors.dart';
|
|
import 'package:chat/routes/moments_routes.dart';
|
|
import 'package:chat/services/auth_service.dart';
|
|
import 'package:chat/services/tabbar_service.dart';
|
|
import 'package:chat/widgets/custom_avatar.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_easyrefresh/easy_refresh.dart';
|
|
import 'package:get/get.dart';
|
|
|
|
class MomentHeader extends StatelessWidget {
|
|
final LinkHeaderNotifier linkNotifier;
|
|
final VoidCallback? onTitleDoubleTap;
|
|
const MomentHeader({
|
|
Key? key,
|
|
required this.linkNotifier,
|
|
this.onTitleDoubleTap,
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return SliverAppBar(
|
|
systemOverlayStyle: SystemUiOverlayStyle.light,
|
|
pinned: true,
|
|
expandedHeight: 260,
|
|
backgroundColor: AppColors.primary,
|
|
foregroundColor: AppColors.white,
|
|
titleTextStyle: const TextStyle(color: AppColors.white),
|
|
leading: CircleHeader(linkNotifier),
|
|
actions: [
|
|
IconButton(
|
|
onPressed: () {
|
|
Get.toNamed(MomentsRoutes.publish);
|
|
},
|
|
icon: const Icon(
|
|
Icons.camera_alt_rounded,
|
|
),
|
|
),
|
|
],
|
|
flexibleSpace: LayoutBuilder(
|
|
builder: (context, constraints) {
|
|
final FlexibleSpaceBarSettings settings = context
|
|
.dependOnInheritedWidgetOfExactType<FlexibleSpaceBarSettings>()!;
|
|
return FlexibleSpaceBar(
|
|
collapseMode: CollapseMode.pin,
|
|
centerTitle: true,
|
|
title: Visibility(
|
|
visible: constraints.maxHeight <= settings.minExtent,
|
|
child: GestureDetector(
|
|
onDoubleTap: () {
|
|
onTitleDoubleTap?.call();
|
|
},
|
|
child: Text(
|
|
'发现',
|
|
style: Theme.of(context)
|
|
.appBarTheme
|
|
.titleTextStyle
|
|
?.copyWith(color: AppColors.white),
|
|
),
|
|
),
|
|
),
|
|
background: const _HeaderBackground(),
|
|
);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _HeaderBackground extends StatelessWidget {
|
|
const _HeaderBackground({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return ColoredBox(
|
|
color: Theme.of(context).scaffoldBackgroundColor,
|
|
child: Stack(
|
|
children: [
|
|
Positioned.fill(
|
|
bottom: 32,
|
|
child: GestureDetector(
|
|
child: Image.asset(
|
|
'assets/images/login_bg.png',
|
|
fit: BoxFit.cover,
|
|
),
|
|
),
|
|
),
|
|
Positioned(
|
|
right: 16,
|
|
bottom: 0,
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
mainAxisAlignment: MainAxisAlignment.end,
|
|
children: [
|
|
SizedBox(
|
|
height: 52,
|
|
child: Obx(() {
|
|
return Text(
|
|
AuthService.to.userInfo.value.nickname ?? '',
|
|
style: const TextStyle(
|
|
color: AppColors.white,
|
|
fontWeight: FontWeight.bold,
|
|
fontSize: 16,
|
|
),
|
|
);
|
|
}),
|
|
),
|
|
const SizedBox(width: 8),
|
|
Obx(() {
|
|
return GestureDetector(
|
|
onTap: () => TabbarService.to.index = 4,
|
|
child: CustomAvatar(
|
|
AuthService.to.userInfo.value.avatar,
|
|
size: 64,
|
|
),
|
|
);
|
|
}),
|
|
],
|
|
),
|
|
)
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
// 圆形Header
|
|
class CircleHeader extends StatefulWidget {
|
|
final LinkHeaderNotifier linkNotifier;
|
|
|
|
const CircleHeader(this.linkNotifier, {Key? key}) : super(key: key);
|
|
|
|
@override
|
|
CircleHeaderState createState() {
|
|
return CircleHeaderState();
|
|
}
|
|
}
|
|
|
|
class CircleHeaderState extends State<CircleHeader> {
|
|
// 指示器值
|
|
double? _indicatorValue = 0.0;
|
|
|
|
RefreshMode get _refreshState => widget.linkNotifier.refreshState;
|
|
double get _pulledExtent => widget.linkNotifier.pulledExtent;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
widget.linkNotifier.addListener(onLinkNotify);
|
|
}
|
|
|
|
void onLinkNotify() {
|
|
if (!mounted) return;
|
|
setState(() {
|
|
if (_refreshState == RefreshMode.armed ||
|
|
_refreshState == RefreshMode.refresh) {
|
|
_indicatorValue = null;
|
|
} else if (_refreshState == RefreshMode.refreshed ||
|
|
_refreshState == RefreshMode.done) {
|
|
_indicatorValue = 1.0;
|
|
} else {
|
|
if (_refreshState == RefreshMode.inactive) {
|
|
_indicatorValue = 0.0;
|
|
} else {
|
|
double indicatorValue = _pulledExtent / 70.0 * 0.8;
|
|
_indicatorValue = indicatorValue < 0.8 ? indicatorValue : 0.8;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Center(
|
|
child: SizedBox.square(
|
|
dimension: 24.0,
|
|
child: CircularProgressIndicator(
|
|
value: _indicatorValue,
|
|
valueColor: const AlwaysStoppedAnimation(AppColors.white),
|
|
strokeWidth: 2.4,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|