Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flutter problem full-screen on android #23913

Closed
1AlexFix1 opened this issue Nov 3, 2018 · 22 comments
Closed

Flutter problem full-screen on android #23913

1AlexFix1 opened this issue Nov 3, 2018 · 22 comments
Assignees
Labels
a: fidelity Matching the OEM platforms better a: layout SystemChrome and Framework's Layout Issues customer: crowd Affects or could affect many people, though not necessarily a specific customer. found in release: 1.21 Found to occur in 1.21 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on P2 Important issues not at the top of the work list platform-android Android applications specifically waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds

Comments

@1AlexFix1
Copy link

1AlexFix1 commented Nov 3, 2018

Hello! I found problems with the SystemChrome.setEnabledSystemUIOverlays ([]) method.
I will try to describe in as much detail as possible.

So, let's begin
I created an empty project and replaced it with this one.

Code

Code taken from here https://flutter.io/cookbook/navigation/navigation-basics/

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: 'Navigation Basics',
    home: FirstScreen(),
  ));
}

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
   print(""" filterLog 
    <<<<<<  FirstScreen build >>>>>>>>
    """);
    return Scaffold(
      appBar: AppBar(
        title: Text('First Screen'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('Launch screen'),
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => SecondScreen()),
            );
          },
        ),
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print(""" filterLog 
    <<<<<< SecondScreen build >>>>>>>>
    """);
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Screen"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Go back!'),
        ),
      ),
    );
  }
}

1. Normal State

Code unchanged.
Check the logs for comparing with the following items and note the movement of the contents inside the window when it is in the tray.

video_1_720

2. Full Screen on

Changes in the code.

  1. Added method SystemChrome.setEnabledSystemUIOverlays ([]);
  2. And Third Screen()

Please note that the widget that started the application does not start the assembly after minimizing the application. However, if you go to the second screen, and then to the third, it will call the build function on all the following screens, except the first, when we return to the application.
Note: In the following paragraph, we consider the option with Navigator.pushReplacement.

video_2_720

3. Full Screen on and change logic next Screen

Changes in the code. The Navigator.push method has been replaced by Navigator.pushReplacement, the second screen is now the main screen, but when we return from the tray, it still calls the build method.
Also note that the second screen is the main one, and when the “Back” button is pressed, the application is hidden and the widget calls the build method !!!!!! What for????? According to the logic of the android, by pressing back button on the root activity, the activity is killed

video_3_720

4. Hide bottom bar

Code changes instead of SystemChrome.setEnabledSystemUIOverlays ([]);
SystemChrome.setEnabledSystemUIOverlays ([SystemUiOverlay.bottom]);

When you open the application, everything is in order, the bottom panel is hidden, but if you tap the screen in any area, it will appear and disappear only after the application goes to the tray and back. The build method is still called after the tray.

video_4_720

5. Hide status bar

Code changes instead of SystemChrome.setEnabledSystemUIOverlays ([]);
SystemChrome.setEnabledSystemUIOverlays ([SystemUiOverlay.top]);

The top pane does not appear when you tap the screen (everything is fine), and not like in the previous example. The assembly method is still called when you go to the tray and back.

video_5_720

6. Full screen mode is enabled using native Android code.

Added the following code

package com.example.flutterbugsystemuioverlays

import android.os.Bundle
import android.view.View
import android.view.WindowManager
import io.flutter.app.FlutterActivity
import io.flutter.plugins.GeneratedPluginRegistrant

class MainActivity(): FlutterActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE
            or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
            or View.SYSTEM_UI_FLAG_FULLSCREEN)
    GeneratedPluginRegistrant.registerWith(this)
  }
}

This is the most interesting case.

  1. In all previous examples, the content inside has shifted when trying to hide the upper or lower bar
  2. For some reason, the lower bar is not hidden, although this code works fine for native applications android
  3. Also note that even though the top bar is hidden, the assembly function in the second screen is not called.

video_6_720

Flutter doctor -v

[✓] Flutter (Channel beta, v0.9.4, on Mac OS X 10.14 18A391, locale ru-RU)
    • Flutter version 0.9.4 at /Users/alexfix/Flutter/flutter
    • Framework revision f37c235c32 (6 weeks ago), 2018-09-25 17:45:40 -0400
    • Engine revision 74625aed32
    • Dart version 2.1.0-dev.5.0.flutter-a2eb050044

[✓] Android toolchain - develop for Android devices (Android SDK 28.0.3)
    • Android SDK at /Users/alexfix/Library/Android/sdk
    • Android NDK at /Users/alexfix/Library/Android/sdk/ndk-bundle
    • Platform android-28, build-tools 28.0.3
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1136-b06)
    • All Android licenses accepted.

[✓] iOS toolchain - develop for iOS devices (Xcode 10.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 10.1, Build version 10B61
    • ios-deploy 2.0.0
    • CocoaPods version 1.5.3

[✓] Android Studio (version 3.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 30.0.1
    • Dart plugin version 181.5656
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1136-b06)

[!] Connected devices
    ! No devices available

Conclusion

It turns out that at the moment it is impossible to use the usual full-screen mode for Android.
The native flutter method calls assembly methods for all screens, except for the first after returning to the applications from the tray.
In addition, the flutter somehow does not allow the native Android code to hide the lower bar, which would be a quick decision to remove the call for the assembly function on all screens, except for the first after the tray in full screen mode

I hope I somehow helped, because I really liked the flutter.

@kyleorin
Copy link

kyleorin commented Nov 5, 2018

@zoechi ..

@zoechi zoechi added framework flutter/packages/flutter repository. See also f: labels. a: fidelity Matching the OEM platforms better f: routes Navigator, Router, and related APIs. labels Nov 5, 2018
@zoechi
Copy link
Contributor

zoechi commented Nov 5, 2018

Please add the output of flutter doctor -v.

@zoechi zoechi added this to the Goals milestone Nov 5, 2018
@1AlexFix1
Copy link
Author

1AlexFix1 commented Nov 5, 2018

Пожалуйста, добавьте вывод flutter doctor -v.

Done, added to description issue .

@GaryQian
Copy link
Contributor

GaryQian commented Dec 5, 2018

Thanks for detailing this. The root cause is how we treat the padding for safe areas. When going full-screen, the safe area padding around the edges are reduced to make use of the new space. However, when the multitasking button is pressed, the navbar reappears, and Flutter responds by changing the padding to accommodate the newly appearing navbar, even though it does not need to.

We should add some smarter logic to distinguish between actual safe-area changes and temporary changes such as those made by the multitasker.

@priezz
Copy link

priezz commented Feb 16, 2019

Hello. I can confirm the same behavior for point 4. (hide the bottom navbar). We would like to hide the bottom controls in our app, but keep the status bar visible. However, the described behavior (tapping anywhere in the screen opens the black bottom navbar, overlapping the app UI, and no way to hide it) prevents us from doing that. At the same time if we hide both nav and status bars, the app works as expected - system controls appear just on the swipe from bottom to top or from top to bottom.

@Nackha1
Copy link

Nackha1 commented Feb 17, 2019

I have the same problem showed in the point 4. I'd like to create a fullscreen app (that keeps the status bar but not the bottom navbar) but it is impossible to accomplish because every time a user taps (anywhere) on the screen the bottom navbar is opened and it can be closed only by going in the apps manager section of Android and returning to the app.
That's line I used: SystemChrome.setEnabledSystemUIOverlays ([SystemUiOverlay.top]);

sososdk pushed a commit to sososdk/flutter_orientation that referenced this issue Mar 20, 2019
@goderbauer goderbauer removed the f: routes Navigator, Router, and related APIs. label Mar 30, 2019
@1AlexFix1
Copy link
Author

Thanks for detailing this. The root cause is how we treat the padding for safe areas. When going full-screen, the safe area padding around the edges are reduced to make use of the new space. However, when the multitasking button is pressed, the navbar reappears, and Flutter responds by changing the padding to accommodate the newly appearing navbar, even though it does not need to.

We should add some smarter logic to distinguish between actual safe-area changes and temporary changes such as those made by the multitasker.

Hi, the problem is already more than six months, will there be any solutions? Since the creation of normal full-screen applications is not possible

@mirjalal
Copy link

Hi, any update with the related bug?

@DjangoOverloard
Copy link

I have a very strange problem and I don't know if they are connected... Somehow when I only show the top system overlay, the rest of the screen becomes inactive. I can't scroll or press anything. But when I go to full screen, display both overlays or only the bottom one this doesn't seem to be the case.

@fredgrott
Copy link

this might not seem obvious but couldn't I abuse the safe areas align widget as a workaround for android as set the values to top and bottom to false just for android?

@loint
Copy link

loint commented Feb 25, 2020

Hi, any update with the related bug ?
I faced same issue.

@Yask0
Copy link

Yask0 commented Feb 27, 2020

Same currently facing case # 4 issue, any updates?

@TahaTesser TahaTesser added a: layout SystemChrome and Framework's Layout Issues platform-android Android applications specifically labels Mar 11, 2020
MesMoustachesDev pushed a commit to azap-tech/linapp-doctor that referenced this issue Mar 21, 2020
## Description

Not totally happy with this: it seems Flutter and Android have issues with fullscreen mode: flutter/flutter#23913
To get out of spinned mode: hold back and overviews buttons.
This only work on Android 5 and later.

## Warning
This still need work, orientation changes seem to be broken
@ErcinDedeoglu
Copy link

@kf6gpe kf6gpe added the P2 Important issues not at the top of the work list label May 29, 2020
@Fleximex
Copy link

Fleximex commented Jul 24, 2020

I feel like this issue deserves a P3 label: https://github.com/flutter/flutter/wiki/Issue-hygiene#priorities
Most users of Flutter are probably using Scaffolds and are hiding top and/or bottom overlays.

There is a fix/hack that works for the keyboard problem (wanting the keyboard to push up the scaffold body, but also wanting to hide the bottom overlay and having the scaffold extend to the bottom of the screen).

If you have a FocusNode attached to the text input widget you use, you can listen to it. Keep a local boolean which you attach to the resizeToAvoidBottomInset parameter of the scaffold. And now when the FocusNode has focus (this is of course not the same as the keyboard showing, but it works) set the parameter to true.
You can start a Flutter project with the following main.dart:

Code
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setEnabledSystemUIOverlays([]);

  runApp(ResizeWithoutWhitespace());
}

class ResizeWithoutWhitespace extends StatefulWidget {
  @override
  _ResizeWithoutWhitespaceState createState() =>
      _ResizeWithoutWhitespaceState();
}

class _ResizeWithoutWhitespaceState extends State<ResizeWithoutWhitespace> {
  final TextEditingController _controller = TextEditingController();
  final FocusNode _focusNode = FocusNode();

  bool resizeBottom = false;

  @override
  void didChangeDependencies() {
    _focusNode.addListener(_setResizeScaffold);
    super.didChangeDependencies();
  }

  void _setResizeScaffold() {
    setState(() {
      resizeBottom = _focusNode.hasFocus;
    });
  }

  @override
  void dispose() {
    _focusNode.removeListener(_setResizeScaffold);
    _focusNode?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        _focusNode.unfocus();
      },
      child: Scaffold(
        resizeToAvoidBottomInset: resizeBottom,
        body: Column(
          children: <Widget>[
            Expanded(
              child: Container(
                margin: EdgeInsets.symmetric(vertical: 32),
                child: Text(
                  'Resize Without Whitespace',
                  textScaleFactor: 1.6,
                ),
              ),
            ),
            TextField(
              focusNode: _focusNode,
              textAlign: TextAlign.center,
              autofocus: false,
              controller: _controller,
              decoration: InputDecoration(
                border: OutlineInputBorder(),
                enabledBorder: OutlineInputBorder(),
              ),
            ),
            Container(
              width: double.maxFinite,
              color: Colors.blue,
              padding: EdgeInsets.symmetric(vertical: 32),
              child: RaisedButton(
                child: Text('Button'),
                onPressed: () {
                  print('button pressed');
                  _focusNode.unfocus();
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}
The GestureDetector Widget in this example makes sure the FocusNode loses focus. And for every other widget that consumes an onTap you also need to programmatically unfocus the FocusNode.

It's not perfect. The user can still dismiss the keyboard without tapping in the app and then the FocusNode doesn't lose focus. So you need to use a package like https://pub.dev/packages/flutter_keyboard_visibility to also listen for that. Of course if that package works well enough you might not need to listen to the FocusNode anymore which will make this easier.

@iapicca
Copy link
Contributor

iapicca commented Jul 27, 2020

Hi @1AlexFix1
testing the code below with the latest master

code
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(const MyApp(key: Key('app')));

class MyApp extends StatelessWidget {
  const MyApp({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) => MaterialApp(
        home: const MyHomePage(
          key: Key('home'),
        ),
      );
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _value;

  @override
  void initState() {
    super.initState();
    _value = 0;
  }

  static const List<String> _values = [
    'normal',
    'fullscreen',
    'hide bottom bar',
    'hide status bar'
  ];

  void _onChanged(int i) {
    switch (i) {
      case 1:
        SystemChrome.setEnabledSystemUIOverlays([]);
        break;
      case 2:
        SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.top]);
        break;
      case 3:
        SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]);
        break;
      default:
        SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);
    }
    setState(() => _value = i);
  }

  @override
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.yellow,
          title: DropdownButton<int>(
            value: _value,
            icon: Icon(Icons.arrow_downward),
            iconSize: 24,
            elevation: 16,
            onChanged: _onChanged,
            items: [
              for (String s in _values)
                DropdownMenuItem(
                  value: _values.indexOf(s),
                  child: Text(s),
                )
            ],
          ),
        ),
        floatingActionButton: FloatingActionButton(
          child: const Icon(Icons.arrow_forward),
          backgroundColor: Colors.yellow,
          onPressed: () => Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => const SecondRoute(key: Key('second')),
            ),
          ),
        ),
      );
}

class SecondRoute extends StatelessWidget {
  const SecondRoute({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(
          title: const Text('second route'),
        ),
        body: const Center(
          child: Text('nothing to see here'),
        ),
      );
}
doctor
[✓] Flutter (Channel master, 1.21.0-6.0.pre.37, on Mac OS X 10.15.5 19F101, locale en-GB)
    • Flutter version 1.21.0-6.0.pre.37 at /Users/nevercode/development/flutter_master
    • Framework revision 35e7005184 (2 days ago), 2020-07-25 09:44:17 -0700
    • Engine revision 626244a72c
    • Dart version 2.9.0 (build 2.9.0-21.0.dev a3815b6590)


[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK at /Users/nevercode/Library/Android/sdk
    • Platform android-29, build-tools 29.0.2
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 11.5)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 11.5, Build version 11E608c
    • CocoaPods version 1.9.0

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.0)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 46.0.2
    • Dart plugin version 193.7361
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)

[✓] VS Code
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.12.2

[✓] Connected device (4 available)
    • Pixel 3a (mobile) • 965AY0WP5C • android-arm64  • Android 10 (API 29)
    • macOS (desktop)   • macos      • darwin-x64     • Mac OS X 10.15.5 19F101
    • Web Server (web)  • web-server • web-javascript • Flutter Tools
    • Chrome (web)      • chrome     • web-javascript • Google Chrome 84.0.4147.89

• No issues found!

the SystemOverlay doesn't appear to work as intended video
Thank you

@iapicca iapicca added found in release: 1.21 Found to occur in 1.21 has reproducible steps The issue has been confirmed reproducible and is ready to work on customer: crowd Affects or could affect many people, though not necessarily a specific customer. labels Jul 27, 2020
@swch01
Copy link

swch01 commented Aug 1, 2020

I am also having the problem described by @ErcinDedeoglu and @Fleximex.

@Hixie Hixie removed this from the None. milestone Aug 17, 2020
@arcas0803
Copy link

Is there any update? I am having issues with the fullscreen too.
When you tap on a textfield, the fullscreen disappear.

@Piinks
Copy link
Contributor

Piinks commented Jul 28, 2021

the SystemOverlay doesn't appear to work as intended video

The linked video showing the expected behavior is not available at this link anymore.

This bug does not appear to be actionable in its current state, as there are a couple of different bugs described here.

We did recently land new Android fullscreen support (flutter/engine#25785, #81303), which deprecates the old SystemChrome.setEnabledSystemUIOverlays in favor of SystemChrome.setEnabledSystemUIMode.

If there is still an issue here, please update the bug. If there is more than one issue, please file a separate bug for each and feel free to tag me. :)

@Piinks Piinks added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Jul 28, 2021
@Piinks Piinks self-assigned this Jul 28, 2021
@Lukiya
Copy link

Lukiya commented Aug 17, 2021

upgraded to 2.5.0-5.1.pre.
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.top])
Above code will hide bottom virtual buttons bar when startup, but once clicked anywhere on the screen, the bottom virtual buttons bar still will show up.

@Piinks
Copy link
Contributor

Piinks commented Aug 17, 2021

SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.top])
Above code will hide bottom virtual buttons bar when startup, but once clicked anywhere on the screen, the bottom virtual buttons bar still will show up.

Hi @Lukiya, that is expected behavior. I do not believe Android will allow you to permanently hide the UI navigation from the user. In your case, tapping the screen brings the overlays back into view. You can listen for this change and respond using SystemChrome.setSystemUIChangeCallback.

This also sounds the same as #62412, see the latest comments there (like this) for more context.

@github-actions
Copy link

Without additional information, we are unfortunately not sure how to resolve this issue. We are therefore reluctantly going to close this bug for now.
If you find this problem please file a new issue with the same description, what happens, logs and the output of 'flutter doctor -v'. All system setups can be slightly different so it's always better to open new issues and reference the related ones.
Thanks for your contribution.

@github-actions
Copy link

github-actions bot commented Sep 1, 2021

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 1, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
a: fidelity Matching the OEM platforms better a: layout SystemChrome and Framework's Layout Issues customer: crowd Affects or could affect many people, though not necessarily a specific customer. found in release: 1.21 Found to occur in 1.21 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on P2 Important issues not at the top of the work list platform-android Android applications specifically waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds
Projects
None yet
Development

No branches or pull requests