Home: samakan ukuran font label menu layanan
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
e273785268
commit
5a8b020256
@@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
@@ -98,16 +100,62 @@ class HomeServiceSection extends StatelessWidget {
|
|||||||
context.router.push(route);
|
context.router.push(route);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const double _horizontalPadding = 16;
|
||||||
|
static const int _crossAxisCount = 4;
|
||||||
|
static const double _crossAxisSpacing = 8;
|
||||||
|
|
||||||
|
/// Semua label memakai ukuran font yang sama: kalau label terpanjang tidak
|
||||||
|
/// muat di lebar sel, semuanya diperkecil bersama supaya tidak ada yang
|
||||||
|
/// kecil sendiri.
|
||||||
|
TextStyle _labelStyle(BuildContext context, double maxWidth) {
|
||||||
|
final style = DefaultTextStyle.of(
|
||||||
|
context,
|
||||||
|
).style.merge(AppStyle.xs.copyWith(fontWeight: FontWeight.w600));
|
||||||
|
final textScaler = MediaQuery.textScalerOf(context);
|
||||||
|
final textDirection = Directionality.of(context);
|
||||||
|
|
||||||
|
final widest = _menus
|
||||||
|
.map((menu) {
|
||||||
|
final painter = TextPainter(
|
||||||
|
text: TextSpan(text: menu.label, style: style),
|
||||||
|
textDirection: textDirection,
|
||||||
|
textScaler: textScaler,
|
||||||
|
maxLines: 1,
|
||||||
|
)..layout();
|
||||||
|
final width = painter.width;
|
||||||
|
painter.dispose();
|
||||||
|
return width;
|
||||||
|
})
|
||||||
|
.reduce(math.max);
|
||||||
|
|
||||||
|
if (widest <= maxWidth) return style;
|
||||||
|
return style.copyWith(fontSize: style.fontSize! * maxWidth / widest);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
return LayoutBuilder(
|
||||||
|
builder: (context, constraints) {
|
||||||
|
final itemWidth =
|
||||||
|
(constraints.maxWidth -
|
||||||
|
_horizontalPadding * 2 -
|
||||||
|
_crossAxisSpacing * (_crossAxisCount - 1)) /
|
||||||
|
_crossAxisCount;
|
||||||
|
final labelStyle = _labelStyle(context, itemWidth);
|
||||||
|
|
||||||
return GridView.builder(
|
return GridView.builder(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
padding: const EdgeInsets.fromLTRB(16, 32, 16, 16),
|
padding: const EdgeInsets.fromLTRB(
|
||||||
|
_horizontalPadding,
|
||||||
|
32,
|
||||||
|
_horizontalPadding,
|
||||||
|
16,
|
||||||
|
),
|
||||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
crossAxisCount: 4,
|
crossAxisCount: _crossAxisCount,
|
||||||
mainAxisSpacing: 12,
|
mainAxisSpacing: 12,
|
||||||
crossAxisSpacing: 8,
|
crossAxisSpacing: _crossAxisSpacing,
|
||||||
mainAxisExtent: 76,
|
mainAxisExtent: 76,
|
||||||
),
|
),
|
||||||
itemCount: _menus.length,
|
itemCount: _menus.length,
|
||||||
@@ -123,16 +171,14 @@ class HomeServiceSection extends StatelessWidget {
|
|||||||
const SizedBox(height: 6),
|
const SizedBox(height: 6),
|
||||||
FittedBox(
|
FittedBox(
|
||||||
fit: BoxFit.scaleDown,
|
fit: BoxFit.scaleDown,
|
||||||
child: Text(
|
child: Text(menu.label, maxLines: 1, style: labelStyle),
|
||||||
menu.label,
|
|
||||||
maxLines: 1,
|
|
||||||
style: AppStyle.xs.copyWith(fontWeight: FontWeight.w600),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user