refactor: replace ClassicHeader with custom refresh header in multiple pages

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
2026-04-29 13:13:07 +07:00
parent e6a30eddd3
commit 8e34d0d479
4 changed files with 98 additions and 4 deletions

View File

@@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@@ -145,7 +147,7 @@ class AppScreen extends StatelessWidget {
enablePullUp: enablePullUp, enablePullUp: enablePullUp,
onRefresh: onRefresh, onRefresh: onRefresh,
onLoading: onLoadMore, onLoading: onLoadMore,
header: refreshHeader, header: refreshHeader ?? _buildDefaultRefreshHeader(),
footer: refreshFooter, footer: refreshFooter,
physics: physics, physics: physics,
child: content, child: content,
@@ -168,6 +170,101 @@ class AppScreen extends StatelessWidget {
); );
} }
Widget _buildDefaultRefreshHeader() {
return CustomHeader(
builder: (context, mode) {
Widget child;
var icon = Icons.arrow_downward;
var text = 'Tarik untuk memuat';
var color = Colors.black;
if (mode == RefreshStatus.canRefresh) {
unawaited(HapticFeedback.lightImpact());
}
switch (mode) {
case null:
return const SizedBox();
case RefreshStatus.idle:
icon = Icons.arrow_downward;
text = 'Tarik untuk memuat ulang';
case RefreshStatus.canRefresh:
icon = Icons.arrow_upward;
text = 'Lepas untuk memuat ulang';
case RefreshStatus.refreshing:
return SizedBox(
height: 60,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
width: 13,
height: 13,
child: CircularProgressIndicator(
strokeWidth: 1.5,
color: Colors.black,
),
),
const SizedBox(width: 10),
Text(
'Sedang memuat halaman, mohon tunggu',
style: AppTextStyles.body,
),
],
),
);
case RefreshStatus.completed:
icon = Icons.check_rounded;
text = 'Berhasil memperbaharui data';
color = Colors.black;
case RefreshStatus.failed:
icon = Icons.close_rounded;
text = 'Gagal memperbaharui data';
color = Colors.black;
case RefreshStatus.twoLevelOpening:
case RefreshStatus.twoLeveling:
case RefreshStatus.twoLevelClosing:
case RefreshStatus.canTwoLevel:
return const SizedBox();
}
child = Row(
key: ValueKey(text),
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, size: 18, color: color),
const SizedBox(width: 8),
Text(
text,
style: AppTextStyles.body.copyWith(color: color),
),
],
);
return SizedBox(
height: 60,
child: Center(
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
transitionBuilder: (child, anim) {
return FadeTransition(
opacity: anim,
child: ScaleTransition(scale: anim, child: child),
);
},
child: child,
),
),
);
},
);
}
Widget _buildBody(BuildContext context) { Widget _buildBody(BuildContext context) {
final content = backgroundWidgets == null final content = backgroundWidgets == null
? _buildBodyContent(context) ? _buildBodyContent(context)

View File

@@ -39,7 +39,6 @@ class _BerkasPageState extends State<BerkasPage> {
refreshController: _refreshController, refreshController: _refreshController,
enablePullDown: true, enablePullDown: true,
onRefresh: _onRefresh, onRefresh: _onRefresh,
refreshHeader: const ClassicHeader(),
body: const SizedBox.shrink(), body: const SizedBox.shrink(),
slivers: [ slivers: [
if (todayBerkas.isNotEmpty) if (todayBerkas.isNotEmpty)

View File

@@ -57,7 +57,6 @@ class _HomeUIState extends State<HomeUI> {
refreshController: _refreshController, refreshController: _refreshController,
enablePullDown: true, enablePullDown: true,
onRefresh: _onRefresh, onRefresh: _onRefresh,
refreshHeader: const ClassicHeader(),
body: Column( body: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [

View File

@@ -70,7 +70,6 @@ class _ProfileUIState extends State<ProfileUI> {
refreshController: _refreshController, refreshController: _refreshController,
enablePullDown: true, enablePullDown: true,
onRefresh: _onRefresh, onRefresh: _onRefresh,
refreshHeader: const ClassicHeader(),
body: Center( body: Center(
child: ConstrainedBox( child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 900), constraints: const BoxConstraints(maxWidth: 900),