fix(android): target API level 35 as required by Google Play
Build & Deploy Farolero / Análisis de código (push) Successful in 14s
Build & Deploy Farolero / Build APK + AAB release (push) Successful in 1m16s

Play rejected version code 54 for still targeting 34.

From API 35 Android forces edge-to-edge: content is drawn behind the system
bars and it is up to each screen to keep clear of them. Seven screens had no
SafeArea and their bottom action button would have ended up under the
gesture bar, so FondoFarolero gains a respetarBarras flag that insets the
content while the background still paints full bleed. The seventeen screens
that already handle it are untouched.

The navigation bar colour is ignored under edge-to-edge, so its icons are
now forced light to stay visible over the dark background.

Verified on the merged manifest: targetSdkVersion 35, and the release bundle
builds. The visual result has not been checked on a device.
This commit is contained in:
2026-07-25 22:27:28 +02:00
parent a890abd9ed
commit ae0d55c00f
10 changed files with 28 additions and 2 deletions
+4 -1
View File
@@ -30,7 +30,10 @@ android {
defaultConfig { defaultConfig {
applicationId = "es.freetimelab.farolero.game" applicationId = "es.freetimelab.farolero.game"
minSdk = 24 minSdk = 24
targetSdk = 34 // Google Play exige 35 como mínimo. A partir de aquí Android impone el
// dibujado de borde a borde: el contenido va detrás de las barras del
// sistema y son las pantallas las que deben apartarse.
targetSdk = 35
versionCode = flutter.versionCode versionCode = flutter.versionCode
versionName = flutter.versionName versionName = flutter.versionName
} }
+4
View File
@@ -20,6 +20,10 @@ void main() {
statusBarColor: Colors.transparent, statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.light, statusBarIconBrightness: Brightness.light,
systemNavigationBarColor: TemaApp.colorFondo, 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()); runApp(const FaroleroApp());
+1
View File
@@ -28,6 +28,7 @@ class _PantallaAjustesState extends State<PantallaAjustes> {
appBar: AppBar(title: Text(l10n.settingsTitle)), appBar: AppBar(title: Text(l10n.settingsTitle)),
body: FondoFarolero( body: FondoFarolero(
intenso: true, intenso: true,
respetarBarras: true,
child: SingleChildScrollView( child: SingleChildScrollView(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Column( child: Column(
@@ -345,6 +345,7 @@ class _PantallaCrearPartidaState extends State<PantallaCrearPartida> {
appBar: AppBar(title: Text(l10n.createGame)), appBar: AppBar(title: Text(l10n.createGame)),
body: FondoFarolero( body: FondoFarolero(
intenso: true, intenso: true,
respetarBarras: true,
child: SingleChildScrollView( child: SingleChildScrollView(
padding: const EdgeInsets.fromLTRB(18, 18, 18, 28), padding: const EdgeInsets.fromLTRB(18, 18, 18, 28),
child: Column( child: Column(
+1
View File
@@ -309,6 +309,7 @@ class _PantallaGestorHostState extends State<PantallaGestorHost> {
), ),
body: FondoFarolero( body: FondoFarolero(
intenso: true, intenso: true,
respetarBarras: true,
child: Padding( child: Padding(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Column( child: Column(
+1
View File
@@ -89,6 +89,7 @@ class _PantallaNotasState extends State<PantallaNotas> {
), ),
body: FondoFarolero( body: FondoFarolero(
intenso: true, intenso: true,
respetarBarras: true,
child: _jugadorSeleccionadoId == null child: _jugadorSeleccionadoId == null
? _construirSelectorJugador(partida) ? _construirSelectorJugador(partida)
: _construirNotas(partida), : _construirNotas(partida),
+1
View File
@@ -118,6 +118,7 @@ class _PantallaNotasOnlineState extends State<PantallaNotasOnline> {
), ),
body: FondoFarolero( body: FondoFarolero(
intenso: true, intenso: true,
respetarBarras: true,
child: _autor == null ? _buildSelector(context) : _buildNotas(context), child: _autor == null ? _buildSelector(context) : _buildNotas(context),
), ),
), ),
+1
View File
@@ -66,6 +66,7 @@ class _PantallaResultadoState extends State<PantallaResultado>
), ),
body: FondoFarolero( body: FondoFarolero(
intenso: true, intenso: true,
respetarBarras: true,
child: Center( child: Center(
child: SingleChildScrollView( child: SingleChildScrollView(
padding: const EdgeInsets.all(32), padding: const EdgeInsets.all(32),
@@ -102,6 +102,7 @@ class _PantallaVotacionClienteState extends State<PantallaVotacionCliente> {
), ),
body: FondoFarolero( body: FondoFarolero(
intenso: true, intenso: true,
respetarBarras: true,
child: Padding( child: Padding(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Column( child: Column(
+13 -1
View File
@@ -139,10 +139,20 @@ class FondoFarolero extends StatelessWidget {
final Widget child; final Widget child;
final bool intenso; final bool intenso;
/// Aparta el contenido de las barras del sistema.
///
/// A partir de targetSdk 35 la app dibuja de borde a borde, así que sin esto
/// lo que quede abajo —normalmente el botón de acción— acaba debajo de la
/// barra de gestos. El fondo se sigue pintando entero; solo se aparta el
/// contenido. Las pantallas que ya envuelven su contenido en SafeArea no
/// necesitan activarlo.
final bool respetarBarras;
const FondoFarolero({ const FondoFarolero({
super.key, super.key,
required this.child, required this.child,
this.intenso = false, this.intenso = false,
this.respetarBarras = false,
}); });
@override @override
@@ -163,7 +173,9 @@ class FondoFarolero extends StatelessWidget {
), ),
), ),
), ),
Positioned.fill(child: child), Positioned.fill(
child: respetarBarras ? SafeArea(child: child) : child,
),
], ],
), ),
); );