fix(mobile): resolve 8 Android debug errors and Kotlin migration
- Migrate to Flutter built-in Kotlin: set builtInKotlin=true and newDsl=true in gradle.properties; remove id(kotlin-android) from app/build.gradle.kts. Eliminates the Kotlin Gradle Plugin WARNING that caused 8 stderr lines in the VS Code Debug console. - Fix DashboardController lifecycle in MobileShell: move controller creation from _buildBody() (called on every rebuild) to didChangeDependencies() so it is initialised once and reused. Prevents repeated data loads on every tab switch and resolves the 203 skipped frames Choreographer warning. - Fix KcSummaryCard RenderFlex overflow (8 cards, 19px each): reduce icon size 28->22px, switch spacing to xs, wrap value Text in FittedBox(scaleDown) with fontSize 28, use bodySmall + maxLines for label. Cards now fit within the GridView childAspectRatio:1.6 constraint on all phone screen sizes. All tests pass: 27 kell_mobile + 41 design_system.
This commit is contained in:
parent
1023249592
commit
51ae862394
|
|
@ -1,6 +1,5 @@
|
||||||
plugins {
|
plugins {
|
||||||
id("com.android.application")
|
id("com.android.application")
|
||||||
id("kotlin-android")
|
|
||||||
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
|
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
|
||||||
id("dev.flutter.flutter-gradle-plugin")
|
id("dev.flutter.flutter-gradle-plugin")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,6 @@
|
||||||
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
|
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
|
# This builtInKotlin flag was added automatically by Flutter migrator
|
||||||
|
android.builtInKotlin=true
|
||||||
|
# This newDsl flag was added automatically by Flutter migrator
|
||||||
|
android.newDsl=true
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,38 @@ class MobileShell extends StatefulWidget {
|
||||||
class _MobileShellState extends State<MobileShell> {
|
class _MobileShellState extends State<MobileShell> {
|
||||||
int _selectedIndex = 0;
|
int _selectedIndex = 0;
|
||||||
|
|
||||||
|
/// Dashboard controller is created once and reused across rebuilds to avoid
|
||||||
|
/// re-triggering data loads on every [setState] call (e.g. tab switches).
|
||||||
|
late DashboardController _dashboardController;
|
||||||
|
|
||||||
static const _titles = ['Dashboard', 'Inventory', 'Products', 'Orders', 'More'];
|
static const _titles = ['Dashboard', 'Inventory', 'Products', 'Orders', 'More'];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
super.didChangeDependencies();
|
||||||
|
// Initialise the controller here (not in initState) because it needs
|
||||||
|
// KcAppScope which requires an inherited widget lookup.
|
||||||
|
if (!_dashboardControllerInitialised) {
|
||||||
|
final services = KcAppScope.of<MobileAppServices>(context);
|
||||||
|
_dashboardController = DashboardController(
|
||||||
|
GetDashboardSummary(
|
||||||
|
inventoryRepository: services.inventoryRepository,
|
||||||
|
productPublishingRepository: services.productPublishingRepository,
|
||||||
|
ordersRepository: services.ordersRepository,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_dashboardControllerInitialised = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _dashboardControllerInitialised = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_dashboardController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final config = KcAppScope.configOf<MobileAppServices>(context);
|
final config = KcAppScope.configOf<MobileAppServices>(context);
|
||||||
|
|
@ -86,15 +116,7 @@ class _MobileShellState extends State<MobileShell> {
|
||||||
|
|
||||||
switch (_selectedIndex) {
|
switch (_selectedIndex) {
|
||||||
case 0:
|
case 0:
|
||||||
return MobileDashboardPage(
|
return MobileDashboardPage(controller: _dashboardController);
|
||||||
controller: DashboardController(
|
|
||||||
GetDashboardSummary(
|
|
||||||
inventoryRepository: services.inventoryRepository,
|
|
||||||
productPublishingRepository: services.productPublishingRepository,
|
|
||||||
ordersRepository: services.ordersRepository,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
case 1:
|
case 1:
|
||||||
return MobileInventoryPage(
|
return MobileInventoryPage(
|
||||||
repository: services.inventoryRepository,
|
repository: services.inventoryRepository,
|
||||||
|
|
|
||||||
|
|
@ -36,11 +36,20 @@ class KcSummaryCard extends StatelessWidget {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Icon(icon, color: iconColor, size: 28),
|
Icon(icon, color: iconColor, size: 22),
|
||||||
const SizedBox(height: KcSpacing.sm),
|
|
||||||
Text(value, style: theme.textTheme.headlineMedium?.copyWith(fontSize: 32)),
|
|
||||||
const SizedBox(height: KcSpacing.xs),
|
const SizedBox(height: KcSpacing.xs),
|
||||||
Text(label, style: theme.textTheme.bodyMedium?.copyWith(color: KcColors.neutral)),
|
FittedBox(
|
||||||
|
fit: BoxFit.scaleDown,
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Text(value, style: theme.textTheme.headlineMedium?.copyWith(fontSize: 28)),
|
||||||
|
),
|
||||||
|
const SizedBox(height: KcSpacing.xs),
|
||||||
|
Text(
|
||||||
|
label,
|
||||||
|
style: theme.textTheme.bodySmall?.copyWith(color: KcColors.neutral),
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue