Why does it show Black screen instead of background image after login in flutter app?

Viewed 2965

I am working on a small app with a login page and a landing page where I want to display a background. On first login, it shows black screen but when I comment this line, it displays red error screen After I remove the commenting, and do Hot reload, it displays the error. When I logout and login again, the whole scenario repeats. Am I missing something? background image works fine for the login page though. I've tried wipe-data and restart emulator as well but to no avail.

// main.dart

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sewer Viewer',
      debugShowCheckedModeBanner: false,
      home: Container(
        decoration: BoxDecoration(
          color: Colors.grey.shade200, //0xff7c94b6
          image: DecorationImage(

// On first login, it shows black screen but when I comment this line, it displays red error screen
// After I remove the commenting, and do Hot reload, it displays the error.
// When I logout and login again, the whole scenario repeats

            image: AssetImage("images/bg.jpg"), 
            fit: BoxFit.cover,
            colorFilter: ColorFilter.mode(
                Colors.green.withOpacity(0.5), BlendMode.dstIn),
          ),
        ),
        child: MainPage(),
      ),
      theme: ThemeData(
        accentColor: Colors.white70,
      ),
    );
  }
}

class MainPage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MainPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.transparent,
      body: Center(
        child: ListView(
          padding: EdgeInsets.all(10.0),
          children: [
            Container(),
          ],
        ),
      ),
      drawer: Drawer(),
    );
  }
}
// login_page.dart
class LoginPage extends StatefulWidget {
  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  SharedPreferences sharedPreferences;
  bool _isLoading = false;
  String _loginMessage = "";

  @override
  void initState() {
    super.initState();
    checkLoginMessages();
  }

  void checkLoginMessages() async {
    sharedPreferences = await SharedPreferences.getInstance();
    if (sharedPreferences.getString("login_message") != null) {
      setState(() {
        _loginMessage = sharedPreferences.getString("login_message");
      });
    } else {
      _loginMessage = "";
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
          decoration: BoxDecoration(
            gradient: LinearGradient(colors: [
              Colors.blue,
              Colors.teal,
            ], begin: Alignment.topCenter, end: Alignment.bottomCenter),
          ),
          child: _isLoading
              ? Center(child: CircularProgressIndicator())
              : Stack(
                  children: <Widget>[
                    Container(
                      decoration: BoxDecoration(
                          image: DecorationImage(
                        image: AssetImage('images/bg.jpg'),
                        fit: BoxFit.cover,
                      )),
                    ),
                    ListView(
                      children: [
                        _headerSection(),
                        _formSection(),
                        _messageSection(),
                        _buttonSection(),
                      ],
                    )
                  ],
                )),
    );
  }

  signIn(String email, String password) async {
    //var jsonData = null;
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    String urlAPI =
        "<SOME_URL_HERE>";
    var body = {'email': email, 'password': password};
    var response = await http.post(urlAPI, body: body);
    if (response.statusCode == 200) {
      var jsonData = jsonDecode(response.body);
      setState(() {
        _isLoading = false;
        sharedPreferences.setString("token", jsonData['userToken']);
        print(response.body);
        Navigator.of(context).pushAndRemoveUntil(
            MaterialPageRoute(builder: (BuildContext context) => MainPage()),
            (Route<dynamic> route) => false);
      });
    } else {
      setState(() {
        _isLoading = false;
        sharedPreferences.setString(
            "login_message", "Incorrect Username/Password");
        Navigator.of(context).pushAndRemoveUntil(
            MaterialPageRoute(builder: (BuildContext context) => LoginPage()),
            (Route<dynamic> route) => false);
      });
      print(response.body);
    }
  }

  TextEditingController emailController = TextEditingController();
  TextEditingController passwordController = TextEditingController();

  Container _messageSection() {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 20.0),
      margin: EdgeInsets.only(top: 30.0),
      child: Text(
        _loginMessage,
        style: TextStyle(color: Colors.yellow, fontSize: 14.0),
      ),
    );
  }

  Container _formSection() {
    return Container(
      padding: EdgeInsets.symmetric(horizontal: 20.0),
      margin: EdgeInsets.only(top: 30.0),
      child: Column(
        children: <Widget>[
          Theme(
            data: ThemeData(
              primaryColor: Colors.orange.shade700,
            ),
            child: txtSection("Email", emailController, Icons.email),
          ),
          SizedBox(
            height: 30.0,
          ),
          Theme(
            data: ThemeData(
              primaryColor: Colors.orange.shade700,
            ),
            child: txtSection("Password", passwordController, Icons.lock),
          ),
          SizedBox(
            height: 30.0,
          ),
        ],
      ),
    );
  }

  Widget txtSection(
          String title, TextEditingController textController, IconData icon) =>
      TextFormField(
        controller: textController,
        obscureText: title != "Password" ? false : true,
        decoration: InputDecoration(
          hintText: title,
          hintStyle: TextStyle(color: Colors.black54),
          icon: Icon(icon),
        ),
      );

  Container _buttonSection() {
    return Container(
      width: MediaQuery.of(context).size.width,
      height: 40.0,
      margin: EdgeInsets.only(top: 30.0),
      padding: EdgeInsets.symmetric(horizontal: 20.0),
      child: RaisedButton.icon(
        onPressed: () {
          setState(() {
            _isLoading = true; // this will allow circularloader to be displayed
          });
          // start signin process
          signIn(emailController.text, passwordController.text);
        },
        icon: Icon(
          Icons.add_to_home_screen,
          color: Colors.white70,
        ),
        color: Colors.green.shade700,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(5.0),
        ),
        label: Text(
          "Sign In",
          style: TextStyle(color: Colors.white70),
        ),
      ),
    );
  }

  Container _headerSection() {
    return Container(
        padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 30.0),
        alignment: AlignmentDirectional.topCenter,
        child: Image.asset('images/logo.png'));
  }
}

Error Log

2020-08-28 04:26:48.688 348-348/? E/netmgr: qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:network' service: Invalid argument
2020-08-28 04:26:48.688 348-348/? E/netmgr: Failed to open QEMU pipe 'qemud:network': Invalid argument
2020-08-28 04:26:48.734 177-182/? E/android.system.suspend@1.0-service: Error opening kernel wakelock stats for: wakeup34: Permission denied
2020-08-28 04:26:48.746 177-182/? E/android.system.suspend@1.0-service: Error opening kernel wakelock stats for: wakeup35: Permission denied
2020-08-28 04:26:48.896 361-361/? E/wifi_forwarder: qemu_pipe_open_ns:62: Could not connect to the 'pipe:qemud:wififorward' service: Invalid argument
2020-08-28 04:26:48.896 361-361/? E/wifi_forwarder: RemoteConnection failed to initialize: RemoteConnection failed to open pipe
2020-08-28 04:26:53.619 177-182/? E/android.system.suspend@1.0-service: Error opening kernel wakelock stats for: wakeup34: Permission denied
2020-08-28 04:26:53.629 177-182/? E/android.system.suspend@1.0-service: Error opening kernel wakelock stats for: wakeup35: Permission denied
2020-08-28 04:27:08.722 177-182/? E/android.system.suspend@1.0-service: Error opening kernel wakelock stats for: wakeup34: Permission denied
2020-08-28 04:27:08.738 177-182/? E/android.system.suspend@1.0-service: Error opening kernel wakelock stats for: wakeup35: Permission denied
2020-08-28 04:27:13.626 177-182/? E/android.system.suspend@1.0-service: Error opening kernel wakelock stats for: wakeup34: Permission denied
2020-08-28 04:27:13.639 177-182/? E/android.system.suspend@1.0-service: Error opening kernel wakelock stats for: wakeup35: Permission denied
2020-08-28 04:27:28.695 177-182/? E/android.system.suspend@1.0-service: Error opening kernel wakelock stats for: wakeup34: Permission denied
2020-08-28 04:27:28.704 177-182/? E/android.system.suspend@1.0-service: Error opening kernel wakelock stats for: wakeup35: Permission denied
2020-08-28 04:27:33.642 177-182/? E/android.system.suspend@1.0-service: Error opening kernel wakelock stats for: wakeup34: Permission denied
2020-08-28 04:27:33.652 177-182/? E/android.system.suspend@1.0-service: Error opening kernel wakelock stats for: wakeup35: Permission denied
2020-08-28 04:27:48.656 177-182/? E/android.system.suspend@1.0-service: Error opening kernel wakelock stats for: wakeup34: Permission denied

After Login After commenting out the background image loading line After de-commenting the line

1 Answers

The reason it shows the black screen is since flutter needs time to load the assets, so it is preferred to pre-Cache the assets. Now this has been a problem for a lot of people when they usually face when they are creating custom splash screens and the asset is heavy

So I followed this github issue This one and stack overflow issues One and Two

So in your code convert the MyApp into the stateful widget

There are two ways you can try both

class _MyAppState extends State<MyApp> {
  var backgroundImage;

  bool init = true;  

  @override
  void didChangeDependencies() {
    if (init) {
      init = false;
      //your code here
      backgroundImage = AssetImage('images/bg.jpg');
      await precacheImage(backgroundImage,context);

    }
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    return Container(); //Will be your MaterialApp here
  }
}

or

class _MyAppState extends State<MyApp> {
  var backgroundImage;

  @override
  void initState() {
    super.initState();
    Future.delayed(Duration.zero).then((_) {
      //Your code here
      backgroundImage = AssetImage('images/bg.jpg');
      await precacheImage(backgroundImage,context);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container();   //Will be your MaterialApp here
  }
}

And make change here

and change here

BoxDecoration(
                          image: DecorationImage(
                        image: backgroundImage,
                        fit: BoxFit.cover,

Well everything I have mentioned is a workaround as the issue is still open so hope this works well.

Related