Files
farolero/lib/main.dart
T
FreeTLab 586b60ae78
Build & Deploy Farolero / Análisis de código (push) Successful in 14s
Build & Deploy Farolero / Build APK + AAB release (push) Successful in 1m28s
fix(android): move MainActivity to the package the manifest looks for
The app crashed on launch with ClassNotFoundException for
es.freetimelab.farolero.game.MainActivity: 374c6ae added the .game suffix to
namespace and applicationId but left the Kotlin source in
es.freetimelab.farolero, so the manifest asked for a class that was never
compiled under that name. Every release built since then died on startup,
including the one already published to internal testing.

Also requests edge-to-edge explicitly now that the app targets 35, rather
than relying on the Flutter default.

Verified on a physical device running Android 16: installs, launches and
stays alive with no crash, and the bottom action buttons sit clear of the
navigation bar.
2026-07-25 23:26:32 +02:00

137 lines
4.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:farolero/l10n/generated/app_localizations.dart';
import 'package:provider/provider.dart';
import 'estado/estado_juego.dart';
import 'servicios/servicio_historial_partidas.dart';
import 'servicios/servicio_idioma.dart';
import 'servicios/servicio_nearby.dart';
import 'servicios/servicio_perfil_usuario.dart';
import 'tema/componentes_farolero.dart';
import 'tema/tema_app.dart';
import 'pantallas/pantalla_principal.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
// Desde targetSdk 35 el dibujado de borde a borde es obligatorio. Se pide
// explícitamente en vez de confiar en el valor por defecto de Flutter; son
// las pantallas, vía SafeArea, las que apartan su contenido de las barras.
// Con navegación de 3 botones el sistema pinta igualmente un velo tras ellos
// y eso no lo controla la app.
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.light,
systemNavigationBarColor: TemaApp.colorFondo,
// Con el dibujado de borde a borde de Android 15 el color de la barra de
// navegación se ignora y queda transparente sobre un fondo oscuro, así
// que sus iconos tienen que ser claros para verse.
systemNavigationBarIconBrightness: Brightness.light,
),
);
runApp(const FaroleroApp());
}
class FaroleroApp extends StatelessWidget {
const FaroleroApp({super.key});
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (_) => EstadoJuego()..cargarBanco(),
),
ChangeNotifierProvider(
create: (_) => ServicioIdioma()..cargar(),
),
ChangeNotifierProvider(
create: (_) => ServicioPerfilUsuario()..cargar(),
),
ChangeNotifierProvider(
create: (_) => ServicioHistorialPartidas()..cargar(),
),
ChangeNotifierProvider(
create: (_) => ServicioNearby(),
),
],
child: Consumer<ServicioIdioma>(
builder: (context, servicioIdioma, _) {
return MaterialApp(
title: 'Farolero',
theme: TemaApp.obtenerTema(),
debugShowCheckedModeBanner: false,
locale: servicioIdioma.locale,
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: ServicioIdioma.localesSoportados,
home: const PantallaCarga(),
);
},
),
);
}
}
class PantallaCarga extends StatelessWidget {
const PantallaCarga({super.key});
@override
Widget build(BuildContext context) {
final estado = context.watch<EstadoJuego>();
final l10n = AppLocalizations.of(context);
if (estado.cargando || estado.banco == null) {
return Scaffold(
body: FondoFarolero(
intenso: true,
child: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 34, vertical: 28),
child: Column(
children: [
const Spacer(flex: 2),
const Icon(
Icons.lightbulb,
color: TemaApp.colorNaranja,
size: 86,
),
const SizedBox(height: 18),
const LogoFarolero(size: 58),
const Spacer(flex: 3),
ClipRRect(
borderRadius: BorderRadius.circular(4),
child: const LinearProgressIndicator(
minHeight: 8,
color: TemaApp.colorNaranja,
backgroundColor: TemaApp.colorSuperficie,
),
),
const SizedBox(height: 14),
Text(
l10n?.loadingWords ?? 'Cargando palabras...',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: TemaApp.colorDorado,
),
textAlign: TextAlign.center,
),
const Spacer(),
],
),
),
),
),
);
}
return const PantallaPrincipal();
}
}