|
|
|
import 'package:flare_flutter/flare_controls.dart';
|
|
|
|
import 'package:flutter/cupertino.dart';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
import 'package:flutter/material.dart'
|
|
|
|
hide RefreshIndicator, RefreshIndicatorState;
|
|
|
|
import 'package:flutter/services.dart';
|
|
|
|
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
|
|
|
import 'package:huixiang/generated/l10n.dart';
|
|
|
|
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
|
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
|
|
import 'package:rive/rive.dart';
|
|
|
|
|
|
|
|
class MyHeader extends StatelessWidget {
|
|
|
|
final Color color;
|
|
|
|
MyHeader({this.color});
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return MyClassicHeader(
|
|
|
|
refreshStyle: RefreshStyle.Follow,
|
|
|
|
completeText: S.of(context).shuaxinchenggong,
|
|
|
|
failedText: S.of(context).shuaxinshibai,
|
|
|
|
refreshingText: S.of(context).shuaxinzhong,
|
|
|
|
releaseText: S.of(context).shifangshuaxin,
|
|
|
|
idleText: S.of(context).xialashuaxin,
|
|
|
|
iconPos: IconPosition.left,
|
|
|
|
completeTextStyle: TextStyle(
|
|
|
|
color:color?? Color(0xFF32A060),
|
|
|
|
),
|
|
|
|
completeIcon: Icon(
|
|
|
|
Icons.done,
|
|
|
|
color: color??Color(0xFF32A060),
|
|
|
|
),
|
|
|
|
refreshingIcon: SpinKitCircle(
|
|
|
|
color: Colors.grey,
|
|
|
|
size: 24.w,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class CustomHeader extends RefreshIndicator {
|
|
|
|
@override
|
|
|
|
State<StatefulWidget> createState() {
|
|
|
|
return _CustomHeader();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class _CustomHeader extends RefreshIndicatorState<CustomHeader> {
|
|
|
|
FlareControls flareController = FlareControls();
|
|
|
|
|
|
|
|
Artboard _riveArtboard;
|
|
|
|
RiveAnimationController _controllerIdle;
|
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
super.initState();
|
|
|
|
|
|
|
|
// rootBundle.load("assets/riv/finger_tapping.riv").then((value) async {
|
|
|
|
rootBundle.load("assets/riv/runner_boy.riv").then((value) async {
|
|
|
|
final riveFile = RiveFile();
|
|
|
|
riveFile.import(value);
|
|
|
|
final artboard = riveFile.mainArtboard;
|
|
|
|
artboard.addController(_controllerIdle = SimpleAnimation("Animation"));
|
|
|
|
// artboard.addController(_controllerIdle = SimpleAnimation("Idle_1"));
|
|
|
|
|
|
|
|
setState(() {
|
|
|
|
_riveArtboard = artboard;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget buildContent(BuildContext context, RefreshStatus mode) {
|
|
|
|
if (_controllerIdle != null) {
|
|
|
|
if (mode == RefreshStatus.idle) {
|
|
|
|
_controllerIdle.isActive = false;
|
|
|
|
} else {
|
|
|
|
_controllerIdle.isActive = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Container(
|
|
|
|
height: 50,
|
|
|
|
child: Rive(
|
|
|
|
artboard: _riveArtboard,
|
|
|
|
alignment: Alignment.center,
|
|
|
|
fit: BoxFit.contain,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class MyClassicHeader extends RefreshIndicator {
|
|
|
|
final OuterBuilder outerBuilder;
|
|
|
|
final String releaseText,
|
|
|
|
idleText,
|
|
|
|
refreshingText,
|
|
|
|
completeText,
|
|
|
|
failedText,
|
|
|
|
canTwoLevelText;
|
|
|
|
final Widget releaseIcon,
|
|
|
|
idleIcon,
|
|
|
|
refreshingIcon,
|
|
|
|
completeIcon,
|
|
|
|
failedIcon,
|
|
|
|
canTwoLevelIcon,
|
|
|
|
twoLevelView;
|
|
|
|
|
|
|
|
/// icon and text middle margin
|
|
|
|
final double spacing;
|
|
|
|
final IconPosition iconPos;
|
|
|
|
|
|
|
|
final TextStyle textStyle;
|
|
|
|
final TextStyle completeTextStyle;
|
|
|
|
|
|
|
|
const MyClassicHeader({
|
|
|
|
Key key,
|
|
|
|
RefreshStyle refreshStyle: RefreshStyle.Follow,
|
|
|
|
double height: 75.0,
|
|
|
|
Duration completeDuration: const Duration(milliseconds: 600),
|
|
|
|
this.outerBuilder,
|
|
|
|
this.textStyle: const TextStyle(color: Colors.grey),
|
|
|
|
this.completeTextStyle: const TextStyle(color: Colors.grey),
|
|
|
|
this.releaseText,
|
|
|
|
this.refreshingText,
|
|
|
|
this.canTwoLevelIcon,
|
|
|
|
this.twoLevelView,
|
|
|
|
this.canTwoLevelText,
|
|
|
|
this.completeText,
|
|
|
|
this.failedText,
|
|
|
|
this.idleText,
|
|
|
|
this.iconPos: IconPosition.left,
|
|
|
|
this.spacing: 15.0,
|
|
|
|
this.refreshingIcon,
|
|
|
|
this.failedIcon: const Icon(Icons.error, color: Colors.grey),
|
|
|
|
this.completeIcon: const Icon(Icons.done, color: Colors.grey),
|
|
|
|
this.idleIcon = const Icon(Icons.arrow_downward, color: Colors.grey),
|
|
|
|
this.releaseIcon = const Icon(Icons.refresh, color: Colors.grey),
|
|
|
|
}) : super(
|
|
|
|
key: key,
|
|
|
|
refreshStyle: refreshStyle,
|
|
|
|
completeDuration: completeDuration,
|
|
|
|
height: height,
|
|
|
|
);
|
|
|
|
|
|
|
|
@override
|
|
|
|
State createState() {
|
|
|
|
return _ClassicHeaderState();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class _ClassicHeaderState extends RefreshIndicatorState<MyClassicHeader> {
|
|
|
|
Widget _buildText(mode) {
|
|
|
|
RefreshString strings =
|
|
|
|
RefreshLocalizations.of(context)?.currentLocalization ??
|
|
|
|
EnRefreshString();
|
|
|
|
return Text(
|
|
|
|
mode == RefreshStatus.canRefresh
|
|
|
|
? widget.releaseText ?? strings.canRefreshText
|
|
|
|
: mode == RefreshStatus.completed
|
|
|
|
? widget.completeText ?? strings.refreshCompleteText
|
|
|
|
: mode == RefreshStatus.failed
|
|
|
|
? widget.failedText ?? strings.refreshFailedText
|
|
|
|
: mode == RefreshStatus.refreshing
|
|
|
|
? widget.refreshingText ?? strings.refreshingText
|
|
|
|
: mode == RefreshStatus.idle
|
|
|
|
? widget.idleText ?? strings.idleRefreshText
|
|
|
|
: mode == RefreshStatus.canTwoLevel
|
|
|
|
? widget.canTwoLevelText ??
|
|
|
|
strings.canTwoLevelText
|
|
|
|
: "",
|
|
|
|
style: mode == RefreshStatus.completed
|
|
|
|
? widget.completeTextStyle
|
|
|
|
: widget.textStyle);
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget _buildIcon(mode) {
|
|
|
|
Widget icon = mode == RefreshStatus.canRefresh
|
|
|
|
? widget.releaseIcon
|
|
|
|
: mode == RefreshStatus.idle
|
|
|
|
? widget.idleIcon
|
|
|
|
: mode == RefreshStatus.completed
|
|
|
|
? widget.completeIcon
|
|
|
|
: mode == RefreshStatus.failed
|
|
|
|
? widget.failedIcon
|
|
|
|
: mode == RefreshStatus.canTwoLevel
|
|
|
|
? widget.canTwoLevelIcon
|
|
|
|
: mode == RefreshStatus.canTwoLevel
|
|
|
|
? widget.canTwoLevelIcon
|
|
|
|
: mode == RefreshStatus.refreshing
|
|
|
|
? widget.refreshingIcon ??
|
|
|
|
SizedBox(
|
|
|
|
width: 25.0,
|
|
|
|
height: 25.0,
|
|
|
|
child: defaultTargetPlatform ==
|
|
|
|
TargetPlatform.iOS
|
|
|
|
? const CupertinoActivityIndicator()
|
|
|
|
: const CircularProgressIndicator(
|
|
|
|
strokeWidth: 2.0),
|
|
|
|
)
|
|
|
|
: widget.twoLevelView;
|
|
|
|
return icon ?? Container();
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
bool needReverseAll() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget buildContent(BuildContext context, RefreshStatus mode) {
|
|
|
|
Widget textWidget = _buildText(mode);
|
|
|
|
Widget iconWidget = _buildIcon(mode);
|
|
|
|
List<Widget> children = <Widget>[
|
|
|
|
iconWidget,
|
|
|
|
SizedBox(
|
|
|
|
width: 10,
|
|
|
|
),
|
|
|
|
textWidget
|
|
|
|
];
|
|
|
|
final Widget container = Padding(padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top,),child: Row(
|
|
|
|
// spacing: widget.spacing,
|
|
|
|
// textDirection: widget.iconPos == IconPosition.left
|
|
|
|
// ? TextDirection.ltr
|
|
|
|
// : TextDirection.rtl,
|
|
|
|
// direction: widget.iconPos == IconPosition.bottom ||
|
|
|
|
// widget.iconPos == IconPosition.top
|
|
|
|
// ? Axis.vertical
|
|
|
|
// : Axis.horizontal,
|
|
|
|
// crossAxisAlignment: WrapCrossAlignment.center,
|
|
|
|
// verticalDirection: widget.iconPos == IconPosition.bottom
|
|
|
|
// ? VerticalDirection.up
|
|
|
|
// : VerticalDirection.down,
|
|
|
|
// alignment: WrapAlignment.center,
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
|
children: children,
|
|
|
|
),);
|
|
|
|
return widget.outerBuilder != null
|
|
|
|
? widget.outerBuilder(container)
|
|
|
|
: Container(
|
|
|
|
child: Center(child: container),
|
|
|
|
height: widget.height,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|