Saturday, March 30, 2019

Flutter - Custom red error widget screen.

When you started work on Flutter application screen design. You definitely face a red screen that shows UI error. It is most irritating and makes us unhappy when you are a beginner.

In Flutter, it’s important to understand how your user experiences these bugs and where those bugs occur. How we can find the bugs with the highest impact and work to fix them. Sometimes, it's necessary to show a meaningful message to make it more sensible for the tester and developer. Flutter framework provides us customization feature to handle these error widget. According to the docs, Flutter shows red screen error whenever a widget fails to build. There is a performRebuild() method inside of StatefulWidget.dart class that invoke to build the widget.
performRebuild
@override void performRebuild() { //..// try { built = build(); debugWidgetBuilderValue(widget, built); } catch (e, stack) { built = ErrorWidget.builder(_debugReportException('building $this', e, stack)); } //..// }
As we can see, the red screen error is nothing but a widget named ErrorWidget provided by the framework. The ErrorWidget will be invoked only when a widget building fails. When widget building fails, Error Widget replaces with your widget. That’s why it's visible only in the area occupied by the widget that has failed to build.




In this post, We going to create a custom red screen error message for a particular case. We'll display red screen error without being depended on widget building fails. We'll display a user-friendly error page instead of showing red exception. The final output will look lie below:



As you can see above, when we enter developerlibs text. It's working fine but when we not entered any text and pushing login button. It's showing red screen error. So,  let's create this example with the help of following steps.

Creating a new Project
1. Create a new project from File ⇒ New Flutter Project with your development IDE.

2. After that open main.dart file and edit it. As we have set our theme and change debug banner property of Application. Now define a method onError which accepts a message string as a parameter. Call setState() to set the _errorMessage field and add a condition to build() method to show ErrorWidget when _errorMessage is not null. Here, if _errorMessage is null ErrorWidget is returned else MaterialApp will be returned.
main.dart
import 'package:flutter/material.dart'; import 'package:flutter_custom_error/home_page.dart'; GlobalKey<MyAppState> rootKey = new GlobalKey(); void main() => runApp( MyApp(key: rootKey), ); class MyApp extends StatefulWidget { MyApp({Key key}) : super(key: key); @override MyAppState createState() { return new MyAppState(); } } class MyAppState extends State<MyApp> { String _errorMessage; onError(String message) { if (mounted) setState(() { _errorMessage = message; }); } @override Widget build(BuildContext context) { return _errorMessage != null ? ErrorWidget(_errorMessage) : MaterialApp( debugShowCheckedModeBanner: false, theme: ThemeData( primaryColor: const Color(0xFF02BB9F), primaryColorDark: const Color(0xFF167F67), accentColor: const Color(0xFF167F67), ), home: HomePage(), ); } }
to track and manage build method error. We have created a key by using the global key. The Global key will uniquely identify elements across the entire app.


3.
Now, create a landing screen of an example where we'll display a text field to enter some text and button for the move to another screen as shown above.

home_page.dart
import 'package:flutter/material.dart'; import 'package:flutter_custom_error/main.dart'; import 'package:flutter_custom_error/second_page.dart'; class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { final teFirstName = TextEditingController(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Login Screen",style: TextStyle(color: Colors.white),), ), body: new Padding( padding: EdgeInsets.fromLTRB(20.0, 50.0, 20.0, 0.0), child: Column( children: <Widget>[ TextField( controller: teFirstName, decoration: InputDecoration( labelText: "Name", hintText: "Name", ), ), new SizedBox( width: 0.0, height: 20.0, ), RaisedButton( onPressed: _showSecondPage, child: Text("Login"), ), ], ), )); } void _showSecondPage() { if (teFirstName.text.isNotEmpty) Navigator.of(context) .push(MaterialPageRoute(builder: (context) => FirstPage(teFirstName.text))); else rootKey.currentState.onError(" Please enter name "); } }
as you can see  _showSecondPage   method. Here, we checking enter text value and showing red screen widget if the user does not enter any text.

4. Here, we have the second screen of the example where we simply displaying text that send from the landing screen.

second_page.dart
import 'package:flutter/material.dart'; class FirstPage extends StatefulWidget { String list; FirstPage(this.list); @override _FirstPageState createState() => _FirstPageState(); } class _FirstPageState extends State<FirstPage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Welcome",style: TextStyle(color: Colors.white),), ), body: Container( child: Center( child: Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ Text( "Hi, " + widget.list.toString(), ), ], ), ), ), ); } }
  

Now, merge all files and run the example. You can see the app running very smoothly as shown above.  But if you are facing any problem or you have any quires, please feel free to ask it from below comment section.

Share:

Get it on Google Play

React Native - Start Development with Typescript

React Native is a popular framework for building mobile apps for both Android and iOS. It allows developers to write JavaScript code that ca...