Pages

Guide: Building a responsive Flutter Web- Part 2

 Let’s continue with the Flutter series and if you haven’t seen part 1, you must check it out first. The first part contains codes to build a web Flutter app and here we have mentioned in detail the layouts of major screens including Tablet, Mobile, and Desktop. In this article, you will get to see how to make a responsive design in Flutter.   





We will start with a new builder package which will be built with a code for a responsive UI to build and maintain an app quickly. First, we need to add a box to the pubspec.    


responsive_builder: ^0.1.2 


UI Implementation

First, we will start building a layout for the mobile screen. 


Navigation Option

In the above responsive framework Flutter example you can that the navigation option is given to the top left of the screen and it moves to the right. First and foremost, we will code for the logo because it will be used in multiple layouts. 


Create a folder named navigation_option and then create a new file under navoption_logo.dart and add the logo image code to this file. 


class NavOptionLogo extends StatelessWidget {

 const NavOptionLogo({Key key}) : super(key: key);


 @override

 Widget build(BuildContext context) {

   return SizedBox(

     height: 80,

     width: 150,

     child: Image.asset('assets/logo.png'),

   );

  }

}

  

We also need to move NavOptionItem into its own widgets. For that, you need to create a new file called navoption_item.dart in the navigation_option folder. Place the _NavOptionItem in the folder. 


class NavOptionItem extends StatelessWidget {

 final String title;

 const NavOptionItem(this.title);

 @override

 Widget build(BuildContext context) {

   return Text(

     title,

     style: TextStyle(fontSize: 18),

   );

 }

}


We have to create a website layout for Tablet/Desktop. With the exact same code, we will create a new file in the navigation_option folder named navigation_option_desktop_tablet.dart. The body from the build function of the navigation_option folder will be added to the dart file. Replace the logo code with a NavOptionLogo widget and remove the (*) symbol from the NavOptionItem


class NavigationOptionDesktopTablet extends StatelessWidget {

 const NavigationOptionDesktopTablet({Key key}) : super(key: key);

 @override

 Widget build(BuildContext context) {

   return Container(

     height: 100,

     child: Row(

       mainAxisAlignment: MainAxisAlignment.spaceBetween,

       children: <Widget>[

         NavOptionLogo(),

         Row(

           mainAxisSize: MainAxisSize.min,

           children: <Widget>[

             NavOptionItem('Policy'),

             SizedBox(

               width: 60,

             ),

             NavOptionItem('About'),

           ],

         )

       ],

     ),

   );

 }

}


After this, we have to set up a layout for a screen type in the main layout file of the navigation_option folder. For this, we need to create a new widget named NavigationOptionMobile in the NavigationOptionDesktopTablet layout. 


import 'package:responsive_builder/responsive_builder.dart';

class NavigationOption extends StatelessWidget {

 const NavigationOption({Key key}) : super(key: key);

 @override

 Widget build(BuildContext context) {

   return ScreenTypeLayout(

     mobile: NavigationOptionMobile(),

     tablet: NavigationOptionDesktopTablet(),

   );

 }

}


Now, let's create a mobile layout. Create a new file named navigation_option_mobile.dart under the folder navigation_option. The first child here is the menu icon symboled as a button and the second child is the NavOptionLogo


class NavigationOptionMobile extends StatelessWidget {

 const NavigationOptionMobile({Key key}) : super(key: key);

 @override

 Widget build(BuildContext context) {

   return Container(

     height: 80,

     child: Row(

       mainAxisSize: MainAxisSize.max,

       mainAxisAlignment: MainAxisAlignment.spaceBetween,

       children: <Widget>[

         IconButton(

           icon: Icon(Icons.menu),

           onPressed: () {},

         ),

         NavOptionLogo()

       ],

     ),

   );

 }

}


After running the above code you will get the result given below. This is all for the navigation option and now we have to add the function to open a drawer when clicking on the icon. 




Let’s now move on to the Home page and build responsive apps with Flutter for the Home page. 


Home

In order to build a home, we have only two layouts in consideration. One layout will be for tablet and mobile and another one will be for Desktop. The CourseDetails will be given under CallToAction for mobile and tablet screens. 


First, we will create a Home for the desktop screen and for that create a new file home_desktop.dart.


class HomeDesktop extends StatelessWidget {

 const HomeDesktop({Key key}) : super(key: key);

 @override

 Widget build(BuildContext context) {

   return Row(

     children: <Widget>[

       CourseDetails(),

       Expanded(

         child: Center(

           child: CallToAction('Join Us'),

         ),

       )

     ],

   );

 }

}


Next, we will create a layout for mobile screens and tablets as well. We need to align everything to the center so that it looks arranged. 


import 'package:flutter/material.dart';

import 'package:the_basics/widgets/call_to_action/call_to_action.dart';

import 'package:the_basics/widgets/course_details/course_details.dart';

class HomeContentMobile extends StatelessWidget {

 const HomeContentMobile({Key key}) : super(key: key);

 @override

 Widget build(BuildContext context) {

   return Column(

     mainAxisSize: MainAxisSize.max,

     mainAxisAlignment: MainAxisAlignment.center,

     children: <Widget>[

       CourseDetails(),

       SizedBox(height: 100,),

       CallToAction('Join Course'),

     ],

   );

 }

}


Move to the HomePage and update the child named Expanded and set it to the ScreenTypeLayout and put your two earlier layouts created for mobile and desktop.


class HomeView extends StatelessWidget {

 @override

 Widget build(BuildContext context) {

   return Scaffold(

     backgroundColor: Colors.white,

     body: CenteredView(

       child: Column(

         children: <Widget>[

           NavigationBar(),

           Expanded(

             child: ScreenTypeLayout(

               mobile: HomeContentMobile(),

               desktop: HomeContentDesktop(),

             ),

           )

         ],

       ),

     ),

   );

 }

}  


Isn’t it easy to create a Flutter responsive layout for two different screen types like desktop and tablet? Take the code from the build function in call_to_action.dart and paste that code to this file. Also, pass the title positional argument through the constructor. 


import 'package:flutter/material.dart';

class CallToActionDesktopTablet extends StatelessWidget {

 final String title;

 const CallToActionDesktopTablet(this.title);

 @override

 Widget build(BuildContext context) {

   return Container(

     padding: const EdgeInsets.symmetric(horizontal: 60, vertical: 15),

     child: Text(

       title,

       style: TextStyle(

         fontSize: 18,

         fontWeight: FontWeight.w800,

         color: Colors.white,

       ),

     ),

     decoration: BoxDecoration(

       color: Color.fromARGB(255, 31, 229, 146),

       borderRadius: BorderRadius.circular(5),

     ),

   );

 }

}

 

Instead of setting up shared decorations and styles for containers, we will just copy and paste it for now. To do that create a new file under call_to_action, with the name call_to_action_mobile.dart.  


class CallToActionMobile extends StatelessWidget {

 final String title;

 const CallToActionMobile(this.title);

 @override

 Widget build(BuildContext context) {

   return  Container(

     height: 60,

     alignment: Alignment.center,

     child: Text(

       title,

       style: TextStyle(

         fontSize: 18,

         fontWeight: FontWeight.w800,

         color: Colors.white,

       ),

     ),

     decoration: BoxDecoration(

       color: Color.fromARGB(255, 31, 229, 146),

       borderRadius: BorderRadius.circular(5),

     ),

   );

 }

}


Lastly, we need to move to call_to_action.dart file and add new widgets for the different layouts. 


class CallToAction extends StatelessWidget {

 final String title;

 CallToAction(this.title);

 @override

 Widget build(BuildContext context) {

   return ScreenTypeLayout(

     mobile: CallToActionMobile(title),

     tablet: CallToActionDesktopTablet(title),

   );

 }

}


And that’s it. We have created a draggable layout for the tablet and mobile with Flutter. Follow the above code to create a responsive design in Flutter. Now you can add widgets according to your requirements. 




Course Details

For this layout, we need to deal with text and style. Here we have to make the text small according to the mobile screen and align it in the center. In the responsive builder Flutter functioning, we will calculate three different values based on the type of screen.  First, the text will be placed on the left side of the screen for the desktop screen, and for mobile, we will keep it in the center. The second will be the title size and the third size of the description for different screens. 


Return ResponsiveBuilder as a root in the CourseDetails widget of your build function. Then do some mathematics and set the values where requires. 


class CourseDetails extends StatelessWidget {

 @override

 Widget build(BuildContext context) {

   return ResponsiveBuilder(builder: (context, sizingInformation) {

     var textAlignment =

         sizingInformation.deviceScreenType == DeviceScreenType.Desktop

             ? TextAlign.left

             : TextAlign.center;

     double titleSize =

         sizingInformation.deviceScreenType == DeviceScreenType.Mobile

             ? 50

             : 80;

     double descriptionSize = sizingInformation.deviceScreenType == DeviceScreenType.Mobile ?

     16 : 21;

     return Container(

       width: 600,

       child: Column(

         crossAxisAlignment: CrossAxisAlignment.start,

         mainAxisAlignment: MainAxisAlignment.center,

         children: <Widget>[

           Text(

             'FLUTTER NEW.\nLEARN BASICS',

             style: TextStyle(

               fontWeight: FontWeight.w800,

               height: 0.9,

               fontSize: titleSize,

             ),

             textAlign: textAlignment,

           ),

           SizedBox(

             height: 30,

           ),

           Text(

             'Flutter is a fast and efficient framework compared to other app development frameworks. It allows the developers to build smooth and easy multi-platform application development.',

             style: TextStyle(

               fontSize: descriptionSize,

               height: 1.7,

             ),

             textAlign: textAlignment,

           )

         ],

       ),

     );

   });

 }

}


And you are done with Course details. All the responsive function is done for the Course Detail. This responsive widget in Flutter will help you build a perfect layout for a mobile screen. 


Navigation Drag

The final responsive UI layout is navigation drag and the below image is how your layout will look like. 





Create a new file named app_colors.dart under the new folder constant under lib. 

import 'package:flutter/rendering.dart';

const Color primaryColor = Color.fromARGB(255, 31, 229, 146);

  

Here you need to create a new folder named nav_drawer and place all the widget items for the drag part here. Create a new file named dgrag_item.dart. This will take icon data and title. The title will be displayed in a folder navoption item, on the other hand, icon will be placed in a normal Icon and not an IconButton


class DragItem extends StatelessWidget {

 final String title;

 final IconData icon;

 const DragItem(this.title, this.icon);

 @override

 Widget build(BuildContext context) {

   return Padding(

     padding: const EdgeInsets.only(left: 30, top: 60),

     child: Row(

       children: <Widget>[

         Icon(icon),

         SizedBox(width: 30),

         NavOptionItem(title),

       ],

     ),

   );

 }

}


Now, we will create a NavigationDragHeadder and create a new file navigation_drag_header.dart under navigation_drag folder.  


class NavigationDragHeader extends StatelessWidget {

 const NavigationDragHeader({Key key}) : super(key: key);

 @override

 Widget build(BuildContext context) {

   return Container(

     height: 150,

     color: primaryColor,

     alignment: Alignment.center,

     child: Column(

       mainAxisSize: MainAxisSize.min,

       children: <Widget>[

         Text(

           'Get Skilled',

           style: TextStyle(

             fontSize: 18,

             fontWeight: FontWeight.w800,

             color: Colors.white,

           ),

         ),

         Text(

           'Click HERE',

           style: TextStyle(color: Colors.white),

         )

       ],

     ),

   );

 }

}


Now use the widgets mentioned above in a column in the container of the body to create a basic drawer body. 

class NavigationDrag extends StatelessWidget {

 const NavigationDrag({Key key}) : super(key: key);

 @override

 Widget build(BuildContext context) {

   return Container(

     width: 300,

     decoration: BoxDecoration(

         color: Colors.white,

         boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 16)]),

     child: Column(

       children: <Widget>[

         NavDragHeader(),

         DragItem('Policy', Icons.videocam),

         DragItem('About', Icons.help),

       ],

     ),

   );

 }

}


Finally, to move towards home_page.dart file and wrap up widgets of Scaffold in a ResponsiveBuilder. 


class HomePage extends StatelessWidget {

 @override

 Widget build(BuildContext context) {

   return ResponsiveBuilder(

     builder: (context, sizingInformation) => Scaffold(

       drawer: sizingInformation.deviceScreenType == DeviceScreenType.Mobile

           ? NavigationDrag()

           : null,

       ...

     ),

   );

 }

}






Make new Model/Controller/Migration in Laravel

  In this article, we have included steps to create a model and controller or resource controller with the help of command line(CLI). Here w...