In my last post, I documented some of the common layouts used in Flutter, and this post is starting to develop an open source Chinese client based on Flutter. In this blog, I want to implement the overall framework of an App, including the Tab navigation menu at the bottom of the page, the page slide menu, and jump to new pages. I hope I can review the old and learn the new while recording, while giving some help to beginners.
The index | The article |
---|---|
1 | Write an open Source Chinese Client based on Flutter from 0 (1) Flutter build | nuggets technical essay introduction and development environment |
2 | Write an open Source Chinese Client based on Flutter from 0 (2) Dart Grammar Basics |
3 | Write an open Source Chinese Client based on Flutter from 0 (3) Introduction to Flutter & Common Widgets |
4 | Write an open Source Chinese Client based on Flutter from 0 (4) Foundation of Flutter layout |
👉 5 | Write an open Source Chinese Client based on Flutter from 0 (5) Set up the overall layout framework of the App |
6 | Write an open Source Chinese Client based on Flutter from 0 (6) Implementation of various static pages |
7 | Write an open Source Chinese Client based on Flutter from 0 (7) App network requests and data stores |
8 | Write an open Source Chinese Client based on Flutter from 0 (8) Use of plug-ins |
Set up the overall layout framework of the App
Apps often used in our daily life, such as wechat, Weibo, QQ, etc., are basically combined by multiple Tab pages at the bottom of the home page and swiping menus. The Open source Chinese client based on Flutter is also an App implemented using this layout combination. The page effect to be achieved in this paper is as shown in the figure below:
The next step is to complete the construction of the layout framework.
New project
File -> New -> New Flutter Project Create a new Flutter project.
The MaterialApp and Scaffold components were used to build the home page
In the newly created Flutter project, delete the code in Lib /main.dart and write the following code:
import 'package:flutter/material.dart';
void main() { runApp(new MyApp()); } // MyApp is a stateful component because the page title, Class MyApp extends StatefulWidget {@Override State<StatefulWidget> createState() => new MyOSCClientState(); } class MyOSCClientState extends State<MyApp> { @override Widget build(BuildContext context) {returnNew ThemealApp (Theme: new ThemeData(// Set page theme Color: const Color(0xFF63CA6C)), Home: new Scaffold(appBar: New AppBar(// set AppBar title: new Text("My OSC"Style: new TextStyle(color: color.white)), // Set the style of the AppBar icon iconTheme: new iconTheme data (color: color.white) Colors.white) ), body: new Text("MyOSC Client"))); }}Copy the code
In the Scaffold appBar property, the theme parameter is set to white for the title. If not set, the default color is black. The iconTheme property of the appBar is also set to a white theme. If not set, the icon on the appBar defaults to black.
Write four pages to switch display
In the lib/ directory of the new Flutter project, create a pages/ directory to hold all the pages in the App, and then create four. Dart files: Dart TweetsListPage. Dart DiscoveryPage. Dart MyInfoPage. Dart code: NewsListPage. Dart
// pages/NewsListPage.dart
import 'package:flutter/material.dart'; Class NewsListPage extends StatelessWidget {@override Widget build(BuildContext context) {return new Center(
child: new Text("NewsListPage")); }}Copy the code
The remaining three pages of code are similar to the above, except for changing the class name and the Text of the Text component.
In the previous step, the body attribute in our Scaffold component was just a Text component. In order to load the four pages above, we used a container component to load the four pages and then switch the pages when tabbed, using the IndexedStack component I mentioned in my previous post. The IndexedStack can have multiple child components, one of which is displayed based on the index value and the others are hidden.
In the first step, define two variables in the MyOSCClientState class: _tabIndex and _body. _tabIndex indicates the Tab index selected at the bottom of the page and _body indicates the body attribute value of the Scaffold component on the home page. Then assign values to the _tabIndex and _body variables as follows:
Int tabindex = 0; Var _body = new IndexedStack(children: <Widget>[ new NewsListPage(), new TweetsListPage(), new DiscoveryPage(), new MyInfoPage() ], index: _tabIndex, );Copy the code
There are four pages loaded with IndexedStack to display when switching tabs, but we don’t have tabs yet. Adding a bottom navigation Tab menu to pages in the Flutter is easy, and there are already many components available.
Write the bottom navigation Tab menu
To add the bottom navigation Tab to the Scaffold, simply add the bottomNavigationBar property to the Scaffold component. This is the bottomNavigationBar property that we use the CupertinoTabBar component provided with the Flutter.
Cupertino Tabbar is the ios-style Tab built into the Flutter. It is used to display several tabs at the bottom of the page. To use the Cupertino style component, you must import the header file.
import 'package:flutter/cupertino.dart';
Copy the code
The CupertinoTabBar component is also simple to use.
new CupertinoTabBar( items: getBottomNavItems(), currentIndex: _tabIndex, onTap: (index) {// Click on the bottom TabItem to change the index value of the currently selected Tab, the page will automatically refreshsetState((){ _tabIndex = index; }); },)Copy the code
Items = List< bottomationBarItem >, currentIndex = TabItem, onTap = TabItem, getBottomNavItems();
List<BottomNavigationBarItem> getBottomNavItems() {
List<BottomNavigationBarItem> list = new List();
for (int i = 0; i < 4; i++) {
list.add(new BottomNavigationBarItem(
icon: getTabIcon(i),
title: getTabTitle(i)
));
}
returnlist; } TextStyle getTabTextStyle(int curIndex) {if (curIndex == _tabIndex) {
return tabTextStyleSelected;
}
returntabTextStyleNormal; } // Image getTabIcon(int curIndex) {if (curIndex == _tabIndex) {
return tabImages[curIndex][1];
}
returntabImages[curIndex][0]; } // return the top title of the page by index value Text getTabTitle(int curIndex) {return new Text(
appBarTitles[curIndex],
style: getTabTextStyle(curIndex)
);
}
Copy the code
Since a TabItem consists of an icon and a text component, you also need to define two variables, tabImages and appBarTitles, in the MyOSCClientState class. TabImages is a two-dimensional array representing ICONS in a TabItem (including ICONS with checked and unchecked status), and appBarTitles is an array of strings representing the page title for each TabItem. The assignment code for these two variables is as follows:
Var tabImages; var tabImages; Var appBarTitles = [var appBarTitles = ['information'.'move'.'found'.'I']; // Data initialization, including TabIcon data and page content data voidinitData() {
if (tabImages == null) {
tabImages = [
[
getTabImage('images/ic_nav_news_normal.png'),
getTabImage('images/ic_nav_news_actived.png')
],
[
getTabImage('images/ic_nav_tweet_normal.png'),
getTabImage('images/ic_nav_tweet_actived.png')
],
[
getTabImage('images/ic_nav_discover_normal.png'),
getTabImage('images/ic_nav_discover_actived.png')
],
[
getTabImage('images/ic_nav_my_normal.png'),
getTabImage('images/ic_nav_my_pressed.png')]]; } // pass in the Image path and return an Image component Image getTabImage(path) {returnNew image. asset(path, width: 20.0, height: 20.0); }Copy the code
To use images in the Image/directory, you must make sure that you have added the path to the Image in the pubspec.yaml file at the root of the project, as shown below:
In order to Tab between different pages, we need to configure a method for the onTap parameter of the CupertinoTabBar component. The method has an index parameter. We will assign the index to the _tabIndex. And execute the assignment in the setState, as follows:
OnTap: (index) {// Click on the bottom TabItem to change the index of the selected Tab, and the page will automatically refreshsetState((){
_tabIndex = index;
});
},
Copy the code
Finally, put the build method code for the MyOSCClientState class:
@override
Widget build(BuildContext context) {
initData();
returnNew ThemealApp (Theme: new ThemeData(// Set page theme Color: const Color(0xFF63CA6C)), Home: new Scaffold(appBar: Title: new Text(appBarTitles[_tabIndex]), // Set AppBar titles to new Text(appBarTitles[_tabIndex]), // Set AppBar titles to new Text(appBarTitles[_tabIndex]) Color.white)), // set the AppBar icon iconTheme: new IconThemeData(color: color.white)), body: CupertinoTabBar is an ios-style bottomNavigationBar component provided by the bottomNavigationBar: new CupertinoTabBar( items: getBottomNavItems(), currentIndex: _tabIndex, onTap: (index) {// Click on the bottom TabItem to change the index value of the currently selected Tab, the page will automatically refreshsetState((){ _tabIndex = index; }); },))); }Copy the code
In the above code, the body property is the _body variable, and the _body variable is an IndexedStack object, and the index of the IndexedStack object is _tabIndex, so when we change _tabIndex in setState, The IndexedStack automatically switches the display subcomponents, thus achieving the purpose of switching pages.
The above code runs in the emulator as shown below:
Add a slide menu to the front page
The slide menu already has components in the Flutter, so adding the slide menu to the first page is simple by passing a drawer parameter to the Scaffold component as follows:
New Scaffold(appBar: new appBar) title: new Text(appBarTitles[_tabIndex]), // Scaffold(appBar: new appBar) New TextStyle(color: color.white)), // Set AppBar icon style iconTheme: new iconTheme Data(color: color.white)), body: CupertinoTabBar is an ios-style bottomNavigationBar component provided by the bottomNavigationBar: new CupertinoTabBar( items: getBottomNavItems(), currentIndex: _tabIndex, onTap: (index) {// Click on the bottom TabItem to change the index value of the currently selected Tab, the page will automatically refreshsetState((){ _tabIndex = index; }); },), // the drawer attribute is used to add a slide menu for the current page. Drawer: New drawer (Child: new Center(Child: New Text(Child: New Text())"this is a drawer")),),)Copy the code
The app running effect after having the drawer is as follows:
Implement the page jump logic
Jumping to the page in the Flutter is very simple using the Navigator API. Let’s change the NewsListPage page and add a button in the middle of the page. Click the button to jump to the details page.
First, create a new NewsDetailPage in the pages/ directory to represent the information details page and add the following code:
import 'package:flutter/material.dart';
class NewsDetailPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Information Details", style: new TextStyle(color: Colors.white)),
iconTheme: new IconThemeData(color: Colors.white)
),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text("News Detail Page."),
new RaisedButton(
child: new Text("Back"), onPressed: () { Navigator.of(context).pop(); },)],)),); }}Copy the code
There are a few things to note in the above code:
- in
build
Method we return a Scaffold component instead of a MaterialApp component as in Main. dart. This is because when we use the Navigator to jump from the list page to the details page, we automatically add a back button to the left of the details page AppBar. If you are still using the MaterialApp object in the details page, the back button will not automatically be added to the top left corner of the page. - The body section of the above code returns a Center component, which contains the Column component, if you do not set it for Column
mainAxisAlignment: MainAxisAlignment.center
, components on the page will be centered only horizontally and not vertically. - use
Navigator.of(context).pop()
Makes the page go back to the previous level.
Next we need to modify the NewsListPage code to add the button and complete the logic to jump to the details page as follows:
import 'package:flutter/material.dart';
import 'NewsDetailPage.dart'; Class NewsListPage extends StatelessWidget {@override Widget build(BuildContext context) {return new Center(
child: new RaisedButton(
child: new Text("to detail page"),
onPressed: () {
Navigator.of(context).push(new MaterialPageRoute(builder: (ctx) {
returnnew NewsDetailPage(); })); })); }}Copy the code
Skip the page using the navigator.of (context).push() method. The push parameter is a Route object, which uses the MaterialPageRoute object provided by the Flutter. The Builder parameter is a method that returns the detail page object.
In addition to using the above method to jump to the page, you can also configure a route parameter for the MaterialApp. The route parameter is similar to a global routing table, according to a name value to navigate to the corresponding page. To do this, define a variable _route of type Map
and assign a value to it in initDate(), as follows:
_routes['newsDetail'] = (BuildContext) {
return new NewsDetailPage();
};
Copy the code
When you need to jump to the page, call the following method to complete the page jump:
Navigator.of(context).pushNamed("newsDetail");
Copy the code
If you need to pass a value to the next page when the page jumps, you can receive the incoming value in the constructor of the next page and then set the incoming value in the component’s constructor when the Navigator calls the push method to new the next page, as described here
The source code
All source code related to this article is available on GitHub as the V0.1 branch of the Demo-Flutter – OSC project.
Afterword.
This article mainly describes the process of building the overall layout framework of the Open source Chinese client based on Flutter. The layout framework can be easily implemented by using the various widgets built into the Flutter. The next article will record the implementation of various static pages of the open source Chinese client based on Flutter.
My open source project
- Google Flutter based on the open source Chinese client, hope you give a Star support, source code:
- GitHub
- Yards cloud
- Tetris based on the Flutter small game, I hope you give a Star support, source:
- GitHub
- Yards cloud
In the previous | The next article |
---|---|
Write an open Source Chinese Client based on Flutter from 0 (4) — Foundation of Flutter layout |
Write an open Source Chinese Client based on Flutter from 0 (6) — Implementation of individual static pages |