In this article, you'll see top 20 UX/UI Design tool to enhance your Designs
UX design is all about providing your users with the information they’re looking for, and doing that in the cleanest and most intuitive way possible. Sounds challenging right? Well that’s just a day in the life of a UX Designer.
While the responsibilities of UX Designers vary from company to company (and even project to project), there are some general functions they all perform irrespective of their companies. Starting with product research, creating personas and information architecture and wrapping things up with wireframes, prototyping and product testing, UX Designers have a broad spectrum of tasks. And with so many tasks at hand, things can get a little sticky if you don’t have the right tools in place to lighten the burden. After all, no artisan really feels complete without their tools, and frankly UX Designers are no exception.
Since designers have to deal with more complex UX issues to make their design more appealing to the targeted audience, they are looking for some tools that can help them automate some tasks or cut down on the complexities. Thankfully, there are hundreds of UX design tools available on the web. Of course, you don’t need all of them. To help you out, here we are bringing a round-up of some cool UX design tools, give them a try.
In this article, we’ve rounded up a list of the most useful tools for UX Designers and to make it a bit more user-friendly, we’ve broken these tools into five different categories: UX Analytics Tools, Session Recording & Heatmapping Tools, A/B Testing Tools, Visual Feedback Tools, and Prototyping & Wireframing Tools.1. Sketch
Sketch is lightweight MacOS based UI tool. Although Photoshop is a personal favorite with the designers, still some have made a switch to Sketch. This super graphic design tool possesses similarity to Photoshop but is more focused on UI/UX design. The tool is powerful, has a wide range of features and brings out professional results. It extends infinite zooming, 2x export, and styled vector shapes which are apt for multiple resolutions. Sketch offers an ‘Export All’ feature and as it is vector-based, there is no problem in exporting PDF, JPG, and PNG (optionally in 2x) files.
Generally, app designers prefer 3 different tools for 3 purposes namely Omnigraffle for wireframing, Photoshop for visual design, and Illustrator for vector logos. All these 3 tools are perfectly aligned with Sketch, thereby making one app fulfill all your needs and achieve overall productivity with no wastage of time.
The sketch is suitable to use owing to its simple operation and the feature which can design the symbols of common elements like buttons, tabs, headers etc with ease. It not only fires up the process of wireframing but also enables an easy hand-off to the visual designers. As we are employing the same tool in the visual design stage, there won’t be much trouble in updating wireframes into high-fidelity visuals.
All the changes that we have witnessed in-app designing have been made possible because of Sketch’s vectorized model, components like multi-resolution exporting and shared styles and symbols.2.Invision
A workflow, collaboration, and prototyping tool that has the capability to convert your static application designs into fully functional prototypes having an interactive nature.
What is even more impressive is the fact that these prototypes carry animations, transitions, and gestures for Android, iOS, as well as responsive web apps.
Let your clients have a firsthand experience of navigating through designs, leading to more sales when displaying to existing or prospective clients.
With Invision, you not only test visuals, but even wireframe flows in a more tangible manner.
Without any kind of coding, you can have designs coming to life, letting you as designers to identify issues and problems upfront, helping you to iterate accordingly.3. MockFlow
MockFlow enables you to build basic layouts quickly
MockFlow is a suite of applications that are very helpful for a number of tasks in the typical project process. Primarily, the WireframePro app is a good alternative prototyping tool for you to use, especially if you’re testing out some new ideas.
If you just need to create wireframes, then take a look at MockFlow. It’s great for working on initial ideas and enables you to build basic layouts quickly, which is sometimes all you need to get thoughts into a presentable form.4. Balsamiq
Balsamiq’s drag-and-drop elements make life easier
If rapid wireframing is what you’re looking for, then Balsamiq is a strong suggestion. You can quickly develop structure and layouts for your projects with ease. The drag-and-drop elements make life easier and you can link buttons to other pages. This means you can quickly start to plan your interfaces and then share them with your team or clients.
With the cloud-based software Pidoco you can create, share and test wireframes, mockups and prototypes. You will be able to add multiple pages and layers, and it also includes a library of drag-and-drop interface elements. Pidoco allows you to share prototypes with clients online and has functions to facilitate feedback and back-and-forth discussion. The price of this tool starts from $12 up to $175 a month (depending on the number of active projects).
Gliffy is a web-based diagram editor. This tool, let users drag and drop components and export images. You have got the possibility to collaborate online and there is also a version tracking function included. Gliffy is recommended for personal use and/or smaller businesses. Pricing ranges between $3.99 to $7.99 a month or you can choose the enterprise option (custom pricing).
Designers are usually forced to come up with manual documentations when creating prototypes for development-ready designs.
UXPin is a great tool for automating the prototyping process and obtaining effective feedback.
UXPin allows the design teams to design, collaborate, and assess the prototypes before the development of the final product.
It works by generating necessary data for developers to use in designing various projects and ensures the prototype is in sync with the projects’ design elements.
Running a live website is a great way for UI designers to ensure any interface issues arising during the design and development of an application are resolved before deployment.
The Visual Inspector tool helps designers to achieve this quickly and without any hassles. It does not require coding or complicated tech skills to get the software running.
Visual Inspector can work with any website template — HTML, WordPress, and other templates.9. InVision
Invision is by far the most popular prototyping tool in the world. Their team is constantly adding new features to help designers prototype more efficiently. With InVision’s project management page, you can organize design components into a status workflow. You can set columns for To-do, In progress, Needs review, and Approved, and drag and drop your design components into the appropriate column.You could add interactions and animations to static images. You can upload multiple file types, including JPG, PNG, GIF, AI, and PSD. It has push and pull integrations with apps like Slack, Dropbox, Box, Trello, JIRA and much more.
It has simplified every aspect of our workflow and collaboration between design and development. One can design better, faster, and more collaboratively with real-time, and it’s in-browser design collaboration and presentation tools. Seamlessly launching meetings and creating guided tours with clients, and also present designs to stakeholders.Many unicorns use this prototyping tools for us UI/UX needs like Uber, Salesforce, Twitter, Linkedin etc which proves that this tool is the best for prototyping.10. Adobe Experience Design
With Adobe XD, you can draw, reuse, and remix vector and build artwork to create wireframes, screen layouts, interactive prototypes, and production-ready assets all in the same app. We can switch easily from design to prototype right within the app. Also, add interactions and transitions and share with teammates and stakeholders to test the look and feel of your design.A product coming from adobe allows integrations with several of its products like Photoshop and After Effects which is a big plus.
Designers can be more productive by just importing files from their tools of Adobe without any hassle.Clients can make comments on your prototypes when you share directly, and view designs in real time on actual devices.11. POP
Transforming your ideas into a workable prototype that people can actually use and share their valuable feedback is a time-consuming task. POP is here to help you out. With this tool, you will be able to build prototype right away without going through the rigorous and time-consuming process of doing it manually.12. Wireframe CC — The minimal quick wireframe tool
**Speed: **Less than10 mins
Wireframe.cc is an online wireframe tool, featuring a simple interface for quickly sketching your wireframes. It even reduces the toolbars and icons of a typical drawing app.
As the tool says itself, it only focuses on the very basics, no interaction or animation are available. The function of Wireframe.cc is basic and quick but kind of limited.
User feedback: “ This quick design software allows you to create the skeleton structure of the website before you go into adding all the complicated content on it. “13. Balsamiq Mockups — A quick wireframe tool based on Flash
Platform: Mac, Window, Web-based
Speed: 5–10 mins
Price: Free trial — 30 days; Pro — $89
Balsamiq Mockups, developed by a software engineer, has won favor by many designers. It’s a great tool for designers to do quick wireframe design.
However, Balsamiq Mockups is not suitable for building large prototypes for the lake of in-depth animations.This is also not the original intention of the tool, which is actually created to do quick and rough wireframes not any prototypes.
User feedback: “ Mockups takes the product design process from hours to minutes… I just mocked up a new interface in about four minutes using the AIR version. So amazing! “14. Fliud UI — A quick wireframe tool focuses on mobile App pattern
**Speed: **10–15 mins
Price: Individual-&8.25 per month; Pro-$19.08 per month; Team-$41.58 per month
Fliud UI is a web-based wireframe tool. Unique with the most wireframe tools, it supports gesture and animation. If you are seeking a tool for high-fidelity wireframe design, Fliud UI maybe your first choice.
But one thing, upload multiple images is not supported.
User feedback: “ It’s a great tool for working the project from scratch, for creating high quality prototype. It’s very easy and intuitive. Sharing is very easy.“
The above are the 5 quick wireframe tools that can help you do real quick wireframe design. Each has their unique features and some cons. But in general, they are a good a tool for quick wireframe design.
Here, I’d like to share my favorite. The quick speed to do a wireframe is the first requirement, they are all in demand. But in the real design process, we usually need more features, such as the design inspiration, various ways of presentation and share, shortest learning curve, flexible interaction and animation, and plenty more easy-to-use settings. With my personal experience, Mockplus is the best one that meets the maximum requirements. It’s absolutely a brand new tool you shouldn’t miss out.15. Principle
Principle is perfect for building great-looking animated interactions
Interaction design is what Principle excels at, especially when it comes to mobile applications. Tweaking and getting animated interactions just right is a breeze with Principle. You can look at individual assets and how they independently animate, right down to timings and easing.16. Atomic
Atomic is another interactive design tool but what sets it apart is the ability to create form elements that you can actually type into. There is also a useful feature that enables you to import data and populate your designs. This really saves some time!17. UXPin
For larger projects and design systems, UXPin’s a top solution
Described as the ‘end-to-end’ UX platform, UXPin is essentially another design tool but with a powerful ability to create design systems. UXPin serves larger design teams that need to work off the same styles and guides, saving time with product development when collaboration plays a large part.18. Flinto (MacOs only)
Price: $99 (there’s a 14-days free trial)
This UI design tool is specialized in creating the design for apps and first of all – mobile apps. With its help, you will be able to add animated transitions among the different screens, create little interactions that will express the behavior of users and easily add scrollable areas with any scrolling animation. It is completely compatible with Sketch and that could make the design creation easier.19. Adobe XD
I’ve already told about Adobe Illustrator previously, and this is another product for designers from Adobe team. As they say on the app’s webpage, that it “is made for designers like you, by designers like us”. I appreciate such an approach very much. The Adobe XD focuses not on drawing, like Illustrator, but on prototyping and collective creation, with sharing and commenting options.20. Marvel
Marvel is web-based app (no need to do any downloading) that has a very shallow learning curve. With an upgraded account, you can make your project a collaborative one. Choose from lots of different prototype frames, from an Apple Watch to an iPhone 6.
You can create screens directly in Marvel or add images from Sketch or Photoshop for example, and sync designs from your cloud storage.
All Marvel’s features are simple and easy to use – such as gestures, layering images and user testing. It also offers a Sketch plugin, which is great if you do lots of app design work in Sketch and want to nick some of the cool features from Marvel, such as the range of gestures and image layering.
What actually IS UX Design? How can you take an experience that already exists, and improve it for the user? In this video, one of our senior product / UX designers, Dee, defines the term 'UX', and describes the 3 essential areas that makes for GREAT User Experiences.
Dee offers practical examples of GOOD and BAD UX Design, and what the implications of each can be, along with insights of what you can expect to do in a UX Design role, based on her 10+ years of experience in the UX industry!
How do you define UX / User Experience Design in 2019?! What insights can you offer on getting started in the industry? Share your thoughts in the comments below!
Thanks for reading ❤
If you liked this post, share it with all of your programming buddies!
A Design Pattern for Flutter
A closer look at a design pattern for Flutter apps
In my last article, I took a look at the example app first introduced Weather App with “flutter_bloc”, and moved it from using Bloc to using a more MVC approach. Below is that article for your reference.
Now in this article, I’m going to take a deeper dive into the MVC approach. This will be like ‘looking under the hood’ of BloC and Redux. In this case, we’re going to be getting into the weeds of the MVC framework as I’ve implemented it. As it would, it’s going to get a little complicated. For some, your eyes may glaze over, but it’s hoped using the same sample app will help us move right along. It‘s going to be long read — make a coffee first.
The MVC design pattern is an explicit effort to separate three aspects of a software application. In this case, Model-View-Controller describes the separation of the app’s Data (Model) from the app’s Interface (View) from the app’s Logic (Controller). If you haven’t already, there’s an article explaining my interpretation of MVC as it was implemented in the Flutter package, mvc_pattern:
Now in this article, the three aspects of the ‘sample app’ are separated even further — incorporating and integrating even further Flutter’s own API and framework. This sample app has its own Github repository called, Weathercast, and is also available on Google Play.
AAs always, I prefer using screenshots over gists in my articles to show code. I find them easier to work with, and easier to read. Click/Tap on the screenshots themselves or on their captions to see the code.
Design patterns provide structure. They provide a means to organize your code. Doing so, it’s hoped, allows developers familiar with the design pattern to ‘hit the ground running’ when assigned to a project. We’re going to see how a design pattern can help organize your code, your files and even your directories that make up your project.
This article will not only suggest a structure, but will also suggest specific programming practices to perform while developing a Flutter app. Note, all suggested here is far from canon. They’re something I do — you may find it useful to do too. In the end, you do what you do.
In this sample app, the MVC design pattern is even conveyed in its directory structure. Looking at the three screenshots below, you’re looking at the directory structure that stores the sample app. Each screenshot is the previous one but with sub directories opened further. Notice there’s some files and even directories named, model, view and controller. Therefore, even at a glance, you know what ‘type’ of code is in what file and in what directory. Nice, no?
Note, in the last two screenshots above, the three library files, model.dart, view.dart and controller.dart are highlighted with little red arrows. They’re now listed below, and you’ll discover each contains a list of export statements. Each represents the ‘three aspects’ of the MVC design pattern. With that, guess what’s contained in the library file, controller.dart. Look closely.
The library file, controller.dart, contains all the ‘controller’ code for the app. So what’s the idea behind all this, you ask. This approach was inspired by the Dart documentation itself when organizing a library package and serves to help expedite the developing phase. I’ll explain.
So, all the source code located under a ‘controller’ directory is listed in the library file, controller.dart. All the source code considered part of ‘the View’ in this app are found in the library file, view.dart. Finally, the file, model.dart, contains references to all the code concerning the app’s data. It’s all part of the practice of organizing the code in such a way in the effort to expedite the development process. Time is money after all.
As an example, you see those three files listed above now referenced in the import statements highlighted by three red arrows in the screenshots below. While developing, the practice of automatically supplying these three import statements right away after you create a ‘new Dart file’ ensures you as a developer that you’ll have all dependencies necessary to get on with your work. Near the end of development, I would then include the ‘show’ directive for future reference (the second screenshot). With that, weeks, months, years from now, I or another developer can then return to this library file, and readily see the dependencies involved. Nice, no?
Admittedly, for larger apps, this practice proves impractical to maintain, but, for simple apps, the idea is to use these three import files to quickly gather the dependencies needed. Time is money.
Notice there’s a directory called, home, in the app’s directory structure. This tells you, at a glance, where the code for the ‘Home’ widget is located. The ‘Home’ widget, as you may know, is usually the main screen for the mobile app in most cases. It’s named after the property found in the class, MaterialApp.
Notice in the last screenshot, under the home directory, there’s another set of directories named, model, view and controller respectively. They’re all pertaining to the ‘Home’ widget. Guess what’s under each directory? See where I’m going with this? At a glance, you can see what code does what.
At a glance, you can see there’s a drawer widget accessed in the ‘Home’ widget. Look at the last screenshot above. See where the drawer code is located? Pretty logical place for it, right? So where’s the data accessed by the ‘Home’ widget, I wonder? Under the directory, model, of course.
So let’s step back a bit, and ask where is this ‘Home’ Widget called in this app? Like with most Flutter apps, you can guess it’s being passed to the ‘home’ property of some MaterialApp widget somewhere. But where? Look below, and you’ll see where.
So there’s the home property being passed the class object, Weather. Where is this class, Weather? Where is this class, WeatherApp? What’s this AppView class that extends WeatherApp? What’s this method, onTheme()? And finally, what’s this con.WeatherApp passed to the property, con? A lot is going on here, uh. We’ll walk through this one step at a time.
First of all, where is this class, Weather? Well, you already have a good idea where that is. It’s the ‘Home’ widget after all. More specifically, it’s the screen or interface for the ‘Home’ widget. You know where the ‘Home’ widget code lives, and you know the ‘interface stuff’ for the ‘Home’ widget is under the directory called, view. Looking there, you’ll see a library file called, of all things, home.dart. Bet it’s in there.
I was right! And unlike Java, you don’t have to name the file after the name of the ‘main’ class in the file. You can have any number of classes, variables and high-level functions in that file! Huge. And so, in the file home.dart, we find the class, Weather. The first part of this class is listed below.
By the way, note the last three import statements above. You’ve seen those three files before. Notice, at a glance, you can determine the dependencies involved in this particular library file. Nice, no?
So where is this class, WeatherApp? It appears to be the start of this app. Note, the class name, WeatherApp, has the word, ‘App’, appended on the end. That should give you a clue as to where this code could be found. Let’s take a look at the sample app’s directory structure again. Notice there’s a directory called, app. Bet, you can guess what’s in there. Yup, three dire…Oops, two directories! Guess the app doesn’t need to access any data. That’s fine.
So, where is this class, WeatherApp? Let’s look at the three screenshots below. Ok, we can figure this out. It’s part of the interface. Hence, it should be under a directory called, view. Looking in the directory, view, we see a library file called, weatherapp.dart. Look’s promising. Let’s open that one up.
This is too easy. We’re getting to know this app pretty fast, aren’t we? Like it’s by design! Take a look below at the class, WeatherApp. Look at the last two import statements. It’s our old friends again — minus the Model. At a glance, you can see what’s being used in this library file and where they live.
Note, the ‘as’ directive is being used on the last import statement. That’s Dart’s way of handling the case when two classes have the same name.
So is this the start of the app? How about we look at the library file, main.dart. By convention, this is the start of most Flutter applications because it contains the function, main().
So, what do you see? You see a class called, App, being instantiated from the library package, mvc_application. Those familiar with my past articles may recognize this as part of my up and coming package release to develop Flutter apps.
You also see our class, WeatherApp, is referenced in one of the three ‘export’ files, view.dart. So, what is the method, runApp(), taking in to start this app? We know the function, runApp(), takes in a Widget, and so we must assume the App object is a Widget. Below is a screenshot of the class, App, and then a screenshot of it’s parent, AppMVC.
Yup, turns out it’s a StatefulWidget. In short, this ‘App’ object starts things using the the following composition: App(View(Controller(Model()))). Note, the last two red arrows in the second screenshot. Those functions, initApp() and init() are going to come up in this article a little shortly.
And so, following this composition, the parameter supplied to the App object must be a ‘View’ of this MVC approach applied to the application. In this case, the ‘View’ is the class, WeatherApp, which extends the class, AppView. We’re peeking ‘looking under the hood’ at this point by the way.
Note, in turn, a Controller is then supplied to the ‘View’ class in the form of con.WeatherApp(). Again, following the composition, App(View(Controller(Model()))).
Notice, I don’t bother passing the Controller as a parameter inside the file, main.dart. Way bother. Make your code more modular, and instantiate the Controller class inside the View in the form of con.WeatherApp(). See below. It happens to have the same class name as the View, WeatherApp, and so the ‘as’ directive to used to make the distinction. That’s fine. Some consistency.
The purpose of this ‘App layer’, by the way, is to set up the ‘environment’ for the app to run on. What you see below is the Controller for the app first instantiated above in the form of, con.WeatherApp().
You can see there’s a lot going on here. As it should, it’s ‘initializing’ the app at startup after all. You can see it extends the class, AppController. Remember those two functions I mentioned earlier, initApp() and init()? Well, they’ve such come into play. See them? We’ll get into specifics on them in a little bit.
Let’s return to the app’s View, also called WeatherApp, for a moment. It extends the class, AppView, and is first instantiated in the file, main.dart. Remember?
Looking at a truncated screenshot of the class, AppView. Here, you can see its build() function. And look! There’s that MaterialApp we’ve been looking for!
In there, we see the MaterialApp class object being supplied an long list of parameters in the form of class variables and or functions. What’s that all about? Well, as you may have already guessed, you’re able to ‘pass in’ all the properties that make up the MaterialApp class with either those variables or functions. And with those functions, you can then dynamically ‘rebuild’ the Widget Tree with new property values if you wish. This feature will, in fact, be demonstrated in the sample app.
By the way, I noted while writing this article that I made a misstep. It’s always good programming practice to keep your code static and immutable if you can. Since there should only be ‘one instance’ of these two classes at the ‘app level,’ the use of static factories make sense, and so the two classes we just covering were changed accordingly:
It’s beyond the scope with this article, but to accentuate the case, here are some reference to Joshua Bloch’s now famous publication: Effective Java. Of course, it doesn’t just apply to Java, but is good practice for any Object-Oriented Programming Language.
Ok, back to it. Now, there’s a drawer used in this app. Remember? How do know? Again, we saw it in the directory structure under the directory, view. See below. Nice.
So further, with this naming convention imposed on the directory structure, you can readily see what makes up the drawer for this particular sample app. Under the directory, drawer, there’s another directory named, weather_locations. Looking inside that directory, we see our old friends again: the directories, controller, model and view. We also see something new. A library file called, mvc.dart.
Looking at the last screenshot above, we can induce weather_locations is another screen displayed inside the drawer. It’s a screen because there’s a directory called, view. There’s a directory called, controller, and there’s even a directory called, model?! There must be data specific to this screen, weather_locations?! Great! Now, what’s this library file, mvc.dart? Let’s take a look at it below.
Well, will you look at that. It contains a list of export statements. A closer look reveals that it’s all the code that makes up the ‘weather location’ screen. The first line contains the model, the second line contains the view and the third contains the controller: M-V-C. All in a file named, mvc.dart. Fun! Look below and you can see the library files it refers to and an example of the ‘weather location’ screen displayed in the drawer.
The files all have the same name — again, adds some consistency, don’t it. Let’s see what’s inside those files. First, we’ll look at the first bit of the Controller:
Note the name of the Controller class. It’s has the abbreviation, Con, append on the end. Developers will then recognize this class as a Controller. (Of course, you could call it anything you want, but there it is.) Note the import statements. They’re using the ‘show’ directive so the next developer who happens to open up this file can readily see what is used and where it lives. Notice the last import statement is that mvc.dart file. All this is an attempt to impose a standard, a conformity, a means to help the next developer ‘hit the ground running’ when this project is handed off to them next.
Let’s take a look that the first bit of the Model class. As always, you can click on the screenshot below and view its full code in Github.
The import statements, at a glance, tells you what classes are involved. The name of the class tells you this is a Model class. Note, like the Controller, it too uses a static factory and not a traditional constructor to instantiate the class. You only need ‘one instance’ of these classes after all. Now, to keep this moving along, what does the View look like?
Looking at the View, you see it’s not even a class but a high-level function?! It returns the variable, _demoItems, of type List<DemoItems>. Looking at the imports you see this View does indeed ‘talk to’ the Controller, LocationCon, and as well as reference the ‘MVC Pattern’ library package’s StateMVC class. So where is this high-level function called in the app?
Because of the way the directory structure is arranged, we can ‘walk this back’ and take a educated guess as to where this high-level function is called. Neat!
Stepping back out of the View, weather_loctions.dart, with the high-level function, we’re still in the drawer directory. Now, going up one level in the directory structure but still in the drawer directory, what do you see? If you guessed it’s called in the file, settings_drawer.dart, you‘d be right.
The first screen shot below is the file, settings_drawer.dart. You can see the function call, LocationCon().listLocations(). This function, in turn, is found in the Controller class, LocationCon. Now that makes sense since, in this MVC arrangement, the View doesn’t directly ‘talk to’ the Model. Instead, your access the high-level function is through the Controller. Looking at the second screenshot, you can see the high-level function we’ve been looking for, weatherLocations, is indeed accessed in the Controller.
Let’s step back, now and look at one particular feature of this sample app. With every weather condition reported, a ‘color theme’ is presented to represent a particular ‘type’ of weather. Gives a little splash to the app.
To be able to ‘dynamically’ change the app’s color theme, you need to be able to call the setState() function on the State object that contains the theme. In other words, the State object that has the class, MaterialApp, in its build() function.
In this sample app, the ‘Theme’ class is a Controller named, ThemeCon, and explicitly changes the color of the app depending on the weather conditions assigned to a location. It controls the color if not the weather.
So where is this ‘Theme Controller?’ It’s located under the ‘Home’ directory. Why? Because it’s called by the ‘Home’ Controller. Where’s the ‘Home’ Controller? It’s found in the file, home.dart. With me so far?
Below, is the stretch of code in the ‘Theme Controller’ responsible for the changing the color theme, and a screenshot of where this file is located.
Now, this ‘Theme Controller’ may be called in the ‘home’ widget, but it’s changing the ‘theme’ property of the MaterialApp class, and we already know that’s back in the ‘App level’ in the State object, AppView. And so, how do you access the app’s State object?— through the app’s Controller of course.
Let’s go back to the app’s Controller, WeatherApp, running at the ‘App Level.’ At last, I’ll be talking about those two functions, initApp() and init().
You can see below the app’s Controller gets access to a lot of things. Make sense — it’s the app’s Controller! In one of those two ‘init’ functions, initApp(), the app’s State object, stateMVC, adds the Controller, ThemeCon. Look below.
In other words, this other Controller called, ThemeCon, is given access to the app’s State object — found in the app’s View, AppView. ThemeCon is now able to call the setState() function in the State object that contains the theme. Are you lost? We’ll step back a little…well actually a lot!
Let’s step back all the way to the beginning. Remember the ‘App’ object that’s passed to the function, runApp()? It’s a StatefulWidget, remember? That means it creates a State object. It creates the app’s State object. Both that StatefulWidget, and its State object, call those two ‘init’ functions respectively. It’s all part of the process in setting up the environment to run your app. Let’s take a peek.
Below are screenshots of my IDE where the execution of the sample app was paused at specific breakpoints. The first screenshot is stopped in the app’s State object’s initState() function. Look at the name of the StatefulWidget function being called there. It too is called, initApp(). Consistency.
The second screenshot has gone into that function up in the Statefulwidget — which you now see is the ‘App’ object passed to the function, runApp(). The breakpoint has stopped on the initApp() belonging to the controller that was assigned to the app’s View. The property, _vw, is the app’s View which is the WeatherApp class in main.dart. Are things coming together for you yet?
Don’t worry if you’re getting lost. I mean, if you’re not the sort who walks through code, for example, trying to get to know how the other design patterns work like Redux, Scoped Model or BLOC, then your probably wasting your time here. Guess, you’re just one of those wants to get it done, right? Although, I will suggest there is less boilerplate in this one. How about reading further? You got this far.
So now we’re back in the initApp() function, where the ‘Theme Controller’ is given access to the app’s State object, stateMVC, highlighted in blue. See?
And so, it turns out, it’s the app’s State object’s initState() function that, in turn, calls the initApp() function in the app’s Controller. It’s all by design.
It’s where synchronous operations are to be performed. Now how about asynchronous?
With any computer program, a lot of things have got to happen before it’s ready for the user to…well, use. There’s a lot of ‘initializing’ to be done first. This is a simple little sample app, but it too has to ‘get ready’ first before it’s, well…ready. Let’s take a further peek at how this Flutter app gets ready.
After the initApp() is called in the app’s State object’s initState() function, the ‘App’ object fires its own build() function. In the first screenshot above, notice the ‘App’ object takes advantage of the FutureBuilder class. The property, future, is given the a function called, init(). Recognize the name?
This is how asynchronous operations are handled. However, it such a way, that the user may have to wait until they’re done. What will the user see til then? The little spinning circle in the center of the screen of course.
In the second screenshot above, you see what’s inside that init() function. It’s stopped at the app’s View own init() function. Let’s look below and see what’s in that init() function. Notice we’re moving up the layers of the framework.
So now, in the first screenshot, we see we’re in the app’s View where some ‘internal’ stuff is done before it stops at the init() function for the parent class, AppViewState. The second screenshot above has us in that init() function where we’re about to now go into the app’s Controller and run its init() function. A lot happening here under the hood — like a framework should.
And now we’re back in the app’s Controller. For our simple little sample app, it’s called, WeatherApp and it’s there, in its init() function, where it actually calls the ‘Location Controller’ — the one we were first introduced to back in the directory, weather_locations. Remember? Here, it’s opening the database that lists the locations on that drawer that’s in the ‘Home’ widget. Remember the drawer? Opening database may take a couple of microseconds, and so the app ‘waits’ for that to get done before it’s ready for the user. Peachy.
There’s another thing called, LocationTimer, listed there as well it would seem, but I’ll let you find out what that is when you download the sample app.
Let’s get back now to how this app changes its color theme on command. The app’s View has a function called, onTheme(). Remember, using such functions allows the MaterialApp to dynamically change its properties the next time it ‘rebuilds’ its Widget tree (i.e. the next time the setState() function is called.) It’s all coming together!
Looking at the ‘Theme Controller’ listed below, you see that the property, theme, is in fact a getter. And, in fact, it’s the function further down below called, weatherChanged(), that ‘reassigns’ a value to the variable, _theme.
And so, going back to the app’s View class, inside the framework, there’s the MaterialApp that takes in either a variable or (if that variable is null) a function. In our sample app, we utilize the function to dynamically assign a new theme. I’d suggest ‘stepping’ through the sample app to see what I mean.
This article is turning into a novel, I know. However, there’s a two more things I want to cover here. Firstly, how does the framework work in performing the main function of this small simple sample app: Get the weather for a city. Let’s do a quick ‘walk-through’ of that. If you’ve read Felix Angelov’s story, Weather App with “flutter_bloc”, you know how it goes. You type in the city’s name, it gets the weather.
Ok, here we go. In the ‘Home’ widget file, home.dart, there’s a State object there that allows you to click on a magnifying glass and type in a city name to get its current weather. Below (just above the little red arrow) there is an IconButton widget that, when pressed, returns a city in a variable called, city. That variable is passed to the ‘Weather Controller.’ See below.
Note, the ‘Weather Controller’ has a function named, onPressed(). I try to follow the practice of mimicking the API used in the View’s code to be also used in the Controller’s code. That consistency thing again. Let’s see where that takes us.
In the onPressed() function listed below, we see the variable, city, is passed along to another function called, getWeather(). We see inside the function, getWeather(), there’s a ‘then’ method. It’s in that ‘then’ method where the function, rebuild(), is called. Finally, the ‘Theme Controller’ comes into the picture to call it’s function, weatherChanged(). Remember that function?
Now, if you guessed that the two functions, refresh(), eventually get to actually calling a State object’s setState() function, you’d be right. Congratulations, you’re starting to see the whole picture.
The ‘Theme Controller’s refresh() function calls the AppView’s State object with its MarterialApp object. This will change the app’s AppBar color. While the second refresh() function you see above calls the ‘Home’ Widget’s State object. This will change the screen’s background color. Magic.
The last thing I want to cover quickly is app preferences. If and when you try out this sample app, you’ll notice it’ll ‘remember’ the last city you picked, and will, in fact, bring up it’s current weather conditions the next time you start up the app. That’s because the ‘last city’ entered is recorded in the app’s preferences — with help from the framework.
The ‘Weather Controller’, WeatherCon, will go and fetch the last city if any in the its initState() function. There, it calls the function, initFetch(). Below is a truncated screenshot of the controller, WeatherCon. The red arrow show you where the app’s preferences is accessed.
You see in the screenshot above where the ‘last city’ is retrieved and, in fact, where the ‘last city’ is recorded — in the function, fetchWeather(). Remember, the function, fetchWeather(), iseventually called every time the user clicks the magnifying glass, and the function, onPressed(), is executed in the View’s code and then in the Controller’s code.
That Prefs class you see in the screenshot above is a library I wrote a few months after first discovering Flutter. I had a need for such a library in my projects, and I talk about that in an article I would then write soon after:
The Prefs library is actually part of the framework I’m working on, and you’ve already seen in being initialized above, in the class AppController, when the app was setting up its environment.
Oh! To heck with it! I decided to publish Prefs as a library package! I just did it! Just now! Here your go: prefs 1.0.2
It’s proven useful in my projects. Might as well as share, right?! Try it out. If you like it, use it. If not, then don’t, right?! Again, read the article above to get the load down on how to use it. It’ll still be a part of the framework when it too gets published. Whenever that’s going to happen?! Just not enough time in the day, is there. Anyway!
Ok, that was bit of a read. I’m sure you’re hungry, and or want to get on with your Life. However, I will be following up on this article as there is much more one has to consider when developing software as you know. It just happens, this framework will allow you to do so, and I’ll show you how in other articles.
Originally published by Greg Perry at https://medium.com