Flutter: Google Translate part 1

Now our component is finally done, we have to add it in our screen page.

And then we should be able to observe a result close to the one I will show.

import 'package:flutter/material.

dart';import '.

/components/choose-language.

dart';class HomePage extends StatefulWidget { HomePage({Key key, this.

title}) : super(key: key); final String title; @override _HomePageState createState() => _HomePageState();}class _HomePageState extends State<HomePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.

title), elevation: 0.

0, ), body: Column( children: <Widget>[ ChooseLanguage(), ), ); }}There is the result of our work!Translate actions UIWe should now create the component to choose the texts we will want to translate.

In the Google application, we must write a text or use different features such as taking a photo.

We are following the same design as in the iOS application.

Accordingly, we will create clickable widgets which will trigger actions in the next parts of this tutorial.

The widget’s structureWe will create the component with this structure using the Columnand Row to display our UI.

The Column works the same way as the Row, the only difference is the direction in which it displays our elements.

We are going to code now in a new component the structure we want to achieve.

import 'package:flutter/material.

dart';class TranslateText extends StatefulWidget { TranslateText({Key key}) : super(key: key); @override _TranslateTextState createState() => _TranslateTextState();}class _TranslateTextState extends State<TranslateText> { @override Widget build(BuildContext context) { return Card( color: Colors.

white, margin: EdgeInsets.

all(0.

0), elevation: 2.

0, child: Container( height: 150.

0, child: Column( mainAxisAlignment: MainAxisAlignment.

spaceBetween, crossAxisAlignment: CrossAxisAlignment.

start, children: <Widget>[ Expanded(.

), Row( mainAxisAlignment: MainAxisAlignment.

spaceBetween, children: <Widget>[ Material( color: Colors.

white, child: Column( children: <Widget>[.

], ), ), ], ), ], ), ), ); }}We are also defining the main and cross axis aligment for our Columnand Row.

Here we chose the MainAxisAlignment.

spaceBetween because we want to have some space between our clickable icons.

Since the structure is coded we can now focus on the input part.

The input part is not a widget in which we will write text.

In the real application when we click on this part, an input appears to write our text.

class _TranslateTextState extends State<TranslateText> { @override Widget build(BuildContext context) { return Card( .

, child: Container( height: 150.

0, child: Column( .

, children: <Widget>[ Expanded( child: InkWell( onTap: () {}, child: Container( width: double.

infinity, padding: EdgeInsets.

only( left: 16.

0, right: 16.

0, top: 16.

0 ), child: Text( "Enter text", style: TextStyle( color: Colors.

grey[700], ), ), ), ), ), Row(.

), ], ), ), ); }}The code is very similar to the first component we created.

It is simply a Text inside of an InkWell.

We are keeping the onTap function for later as we did in the first component we created.

We have now to create the clickable icons in the Row.

We are going to use the same code to display the 4 icons with its descriptive text.

We could just write 4 times the same code in the Row nevertheless we are going to duplicate the code if we do so.

With this method we will have to change the code as many times as we duplicated it.

The best solution is to create another component that we will call four times with different arguments.

Creation of a clickable iconimport 'package:flutter/material.

dart';class ActionButton extends StatefulWidget { ActionButton({Key key, this.

icon, this.

text, this.

imageIcon}) : super(key: key); final IconData icon; final AssetImage imageIcon; final String text; @override _ActionButtonState createState() => _ActionButtonState();}class _ActionButtonState extends State<ActionButton> { @override Widget build(BuildContext context) { return Material( color: Colors.

white, child: FlatButton( padding: EdgeInsets.

only( left: 8.

0, right: 8.

0, top: 2.

0, bottom: 2.

0, ), onPressed: () {}, child: Column( children: <Widget>[.

], ), ), ); }}We called our new component ActionButton and unlike the others we added arguments icon, imageIcon and text.

Some of the icons I used were not in the Google Library so I created my owns.

That’s why I make the difference between icon and ImageIcon.

We are going to create a function to display the icon from an IconData or an AssetImage.

Widget _displayIcon() { if (this.

widget.

icon != null) { return Icon( this.

widget.

icon, size: 23.

0, color: Colors.

blue[800], ); } else if (this.

widget.

imageIcon != null) { return ImageIcon( this.

widget.

imageIcon, size: 23.

0, color: Colors.

blue[800], ); } else { return Container(); }}This function check if the icon or the imageIcon variables are null, when one of the both isn’t then we display the image with it’s right component.

Indeed we display IconData thanks to the Icon component.

The AssetImage thanks to the ImageIcon component.

I also added the possibility than not any of them is declared, in which we are going toi display an empty Container.

@overrideWidget build(BuildContext context) { return Material( color: Colors.

white, child: FlatButton( .

, child: Column( children: <Widget>[ _displayIcon(), Text( this.

widget.

text, style: TextStyle(fontSize: 12), ), ], ), ), );}We added the _displayIcon function in our Column right behind the text.

It will display the right widget from the icon or the image icon we are going to pass to our component.

We can call now our component in the TranslateText we created earlier.

import 'package:flutter/material.

dart';import 'ActionButton.

dart';class _TranslateTextState extends State<TranslateText> { @override Widget build(BuildContext context) { return Card( .

, child: Container( height: 150.

0, child: Column( .

, children: <Widget>[ Expanded( .

, ), Row( mainAxisAlignment: MainAxisAlignment.

spaceBetween, children: <Widget>[ ActionButton( icon: Icons.

camera_alt, text: "Camera", ), ActionButton( imageIcon: AssetImage("assets/pen.

png"), text: "Handwriting", ), ActionButton( imageIcon: AssetImage("assets/conversation.

png"), text: "Conversation", ), ActionButton( icon: Icons.

keyboard_voice, text: "Voice", ), ], ), ], ), ), ); }}We imported our component and we called ActionButton 4 times with different arguments to have a unique render for each ActionButton but still the same code.

Add assets images (optionnal)I added my own images in some buttons we just made but we need to change the file pubspec.

yaml in the root folder to display these images.

flutter: # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class.

uses-material-design: true # To add assets to your application, add an assets section, like this: assets: – assets/I added the “- assets/” in the pubspec.

yaml file and created an assets folder in the root folder with my images.

When this is done you might need to rerun the application.

Finally, you could call your images like I did before, for exemple: AssetImage("assets/pen.

png").

If you want to know more about assets and how we can use them, I invite you to read the excellent Flutter documentation below.

Adding assets and imagesFlutter apps can include both code and _assets_ (sometimes calledresources).

An asset is a file that is bundled and…flutter.

ioLooking at our workThe second component is completed, the application’s UI is almost done now.

Display the list of last translatesWe need to create again a new component to display the list of the last translates we did.

Still using the same principle, we will develop a widget combining rows and columns.

The List will display our items like a Column does except that it will be automatized without adding `n` times the components.

Furthermore, it will display a scrolling on the list.

First of all, I define a Translate class which is composed of the elements we will need to display the items in our list.

class Translate { String text; String translatedText; bool isStarred; Translate(String text, String translated, bool isStarred) { this.

text = text; this.

translatedText = translated; this.

isStarred = isStarred; }}Since the Translate class is created we can create our new component that I called `ListTranslate`.

We define the number of lines the ListView is going to display in ItemCoun.

In ItemBuilder we display the rows with our array list.

import 'package:flutter/material.

dart';import '.

/models/translate.

dart';class ListTranslate extends StatefulWidget { ListTranslate({Key key}) : super(key: key); @override _ListTranslateState createState() => _ListTranslateState();}class _ListTranslateState extends State<ListTranslate> { List<Translate> _items = []; Widget _displayCard(int index) { return Card( child: Container( ), ); } @override Widget build(BuildContext context) { return Expanded( child: ListView.

builder( itemCount: _items.

length, itemBuilder: (BuildContext ctxt, int index) { return _displayCard(index); }, ), ); }}The next step is creating the list’s items like in the sketch we made earlier.

To do so, we are going to use Row and Column as we did for the last components.

Nevertheless, we are going to add some style like a border radius, margin and padding to give it a better style.

Widget _displayCard(int index) { return Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.

all(Radius.

circular(0.

0)), ), margin: EdgeInsets.

only(left: 8.

0, right: 8.

0, top: 0.

5), child: Container( height: 80.

0, padding: EdgeInsets.

only(left: 16.

0, top: 16.

0, bottom: 16.

0), child: Row( mainAxisAlignment: MainAxisAlignment.

spaceBetween, children: <Widget>[ Flexible( child: Column( crossAxisAlignment: CrossAxisAlignment.

start, mainAxisAlignment: MainAxisAlignment.

spaceAround, children: <Widget>[ Text( _items[index].

text, style: TextStyle( fontWeight: FontWeight.

w600, ), maxLines: 1, overflow: TextOverflow.

ellipsis, ), Text( _items[index].

translatedText, style: TextStyle( fontWeight: FontWeight.

w400, ), maxLines: 1, overflow: TextOverflow.

ellipsis, ), ], ), ), IconButton( onPressed: () {}, icon: Icon( Icons.

star_border, size: 23.

0, color: Colors.

grey[700], ), ), ], ), ), );}It displays now each rows in our list with the information we will find in our list.

The Flexible widget will take the place it needs for our texts to display correctly.

If our texts are too long they are going to be cut at the end thanks to the maxLine and overflow we added in the Text.

IconButton( onPressed: () {}, icon: Icon( _items[index].

isStarred ? Icons.

star : Icons.

star_border, size: 23.

0, color: _items[index].

isStarred ? Colors.

blue[600] : Colors.

grey[700], ),),We want to change the color and the icon if the row’s element has been starred.

We use the ternary operators to change it directly from the list information.

List<Translate> _items = [ Translate( "yellowish", "jaunâtre", true, ), .

,];We fill the list’s items with arbitraty information to see how it is going to looks like.

And now, the design is finally completed, we can observe the work we made during all this session.

ConclusionIt shows how easy and fast it is to create a mobile application for Android and IOS with Flutter.

We find also some parts that look like flexbox in the web development.

Even if it’s a development very specific to mobile, web developers could find similarities withwhat they know.

We only did a basic application without any features yet but it’s not going to be harder for the next parts !This is my first article and english isn’t my main language.

I hope you will be comprehensive with the mistakes I surely did.

It’s an exercise I wanted to do to improve my english and share with you what I know about Flutter.

Share a technology I fell in love with.

Thanks.

Github Linkhttps://github.

com/Appli-chic/google-translate-flutter/tree/part-1.. More details

Leave a Reply