• 原文地址:Flutter Getting Started: Tutorial 5 Grid
  • Original article by Alok Gupta
  • Translation from: The Gold Project
  • This article is permalink: github.com/xitu/gold-m…
  • Translator: YueYong

introduce

The Flutter GridView is almost identical to the ListView except that it provides a 2D comparison to the ListView’s unidirectional view. It is also a popular widget for mobile application development. If you don’t believe me, for example, open any e-commerce app on your phone, and it relies on a ListView or GridView to display data.

The Amazon mobile application uses a grid to display data

Another is PayTM, one of the popular online wallet services in India, which makes extensive use of a grid layout to display different products

background

The ultimate goal of this article is to achieve a similar interface:

However, if you notice the image above, it’s in landscape mode. So in this article, I’ll do the following: When the application is in portrait mode, the mobile APP will display items in the ListView, and when it is in landscape mode, it will display three items per row in the grid. I also implemented the creation of custom widgets by moving the GridView in a separate class.

Use the code

I’m going to build on my previous article Flutter Getting Started: Tutorial 4 ListView. I’ve created an application based on the ListView. Here is the initial project structure and initial UI.

This is the initial code we started building

class HomePage extends StatelessWidget {
  final List<City> _allCities = City.allCities();

  HomePage() {}
  final GlobalKey scaffoldKey = new GlobalKey();
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        key: scaffoldKey,
        appBar: new AppBar(
          title: new Text(
            "Cites around world", style: new TextStyle(fontSize: 18.0, fontWeight: fontweight.bold, color: color.black87),),), body: New Padding(Padding: edgeinset.fromltrb (0.0, 10.0, 0.0, 0.0), child: getHomePageBody(context))); } getHomePageBody(BuildContext context) {return ListView.builder(
        itemCount: _allCities.length,
        itemBuilder: _getListItemUI,
        padding: EdgeInsets.all(0.0),
      );
   
  }

  Widget _getListItemUI(BuildContext context, int index,
      {double imgwidth: 100.0}) {
    return new Card(
        child: new Column(
      children: <Widget>[
        new ListTile(
          leading: new Image.asset(
            "assets/"+ _allCities[index].image, fit: BoxFit.fitHeight, width: imgwidth, ), title: new Text( _allCities[index].name, style: New TextStyle(fontSize: 14.0, fontWeight: fontweight.bold),), subtitle: New Column(mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[new Text(_allCities[index]. Country, style: new TextStyle(fontSize: 13.0, fontWeight: 13.0) FontWeight.normal)), new Text('Population: ${_allCities[index].population}', style: new TextStyle(fontSize: 11.0, fontWeight: fontweight.normal),]), onTap: () { _showSnackBar(context, _allCities[index]); },)],)); } _showSnackBar(BuildContext context, City item) { final SnackBar objSnackbar = new SnackBar( content: new Text("${item.name} is a city in ${item.country}"), backgroundColor: Colors.amber, ); Scaffold.of(context).showSnackBar(objSnackbar); }}Copy the code

Before I get to the actual task, let me give you a brief overview of what I’ve done above

  • I have usedListView.builderCreated a simpleListView, it has the flexibility to create infinite Listitem views because it only calls callback functions for those items that can be displayed on the screen.
  • I am showing the city information, such as the city landmark image, followed by the city name, the country the city belongs to and its population.
  • Finally click, and it displays a small message at the bottom of the screen that automatically disappears, calledSnackBar.

Now to get to work, as I mentioned earlier, we’ll refactor the new widget into different classes to keep our code modular and improve readability. So, create a new folder under the lib folder and add the new DART file myGridView.dart.

After adding files, first by ‘package: flutter/material. The dart’ import material components, and then add MyGridView class to inherit our favorite StatelessWidget and autotype Build function, the code is shown below

import 'package:flutter/material.dart';
import 'package:flutter5_gridlist/model/city.dart';

class MyGridView extends StatelessWidget {
  final List<City> allCities;
  MyGridView({Key key, this.allCities}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    returnnull; }}Copy the code

I’m now adding the basic GridView to show only city names, so I’ll add the following code to the rewritten Build function

@override
Widget build(BuildContext context) {
  return GridView.count(
    crossAxisCount: 3,
    padding: EdgeInsets.all(16.0),
     childAspectRatio: 8.0,
    children: _getGridViewItems(context),
  );
}
_getGridViewItems(BuildContext context){
  List<Widget> allWidgets = new List<Widget>();
  for (int i = 0; i < allCities.length; i++) {
    var widget = new Text(allCities[i].name);
    allWidgets.add(widget);
  };
  return allWidgets;
}
Copy the code

Explanation of the above code

  • GridView.countMethod will provide the GridView widget to the application
  • crossAxisCountProperty is used to let the mobile application know how many items per row we want to display
  • childrenProperty will contain all the widgets that you want to display when the page loads
  • childAspectRatio, which is the ratio of the horizontal axis to the main axis range of each child node, and since I am displaying the name, I uniformly set it to 8.0 to reduce the margin between the two blocks

This is what the UI looks like

Now let’s change the UI to look like the ListView that we saw. Here I’ve created a new function that will send the City class as Card

// Create individual item
_getGridItemUI(BuildContext context, City item) {
  return new InkWell(
      onTap: () {
        _showSnackBar(context, item);
      },
      child: new Card(
        child: new Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            new Image.asset(
              "assets/"+ item.image, fit: BoxFit.fill, ), new Expanded( child: new Center( child: new Column( children: <Widget>[new SizedBox(height: 8.0), new Text(item.name, style: new TextStyle(fontSize: 20.0, fontWeight: 20.0) FontWeight.bold, ), ), new Text(item.country), new Text('Population: ${item.population}')],)))]), elevation: 2.0, margin: EdgeInsets. All (5.0),)); }Copy the code

Explanation of the above code

  • I’m usingInkwellClass, since the Card class doesn’t support gestures directly, I wrapped it in the InkWell class to take advantage of itsonTapEvent to replace SnackBar
  • The rest of the code looks like thisListViewOf the card, but no width is specified
  • Also, since we’re showing the full card, let’s not forget tochildAspectRatioChanged from 8.0 to 8.0/9.0 because we need more height.

If you remember, I said at the beginning of the program that I was going to display the ListView in portrait and the GridView in landscape, and to do that we need the MediaQuery class to identify the direction. Whenever you change direction, you can decide which code should be called, that is, the Build function is called even if you tilt the window and the widget is redrawn. So in our homepage.dart class we’ll use the following functions to handle Orientation changes

getHomePageBody(BuildContext context) {
  if (MediaQuery.of(context).orientation == Orientation.portrait)
    return ListView.builder(
      itemCount: _allCities.length,
      itemBuilder: _getListItemUI,
      padding: EdgeInsets.all(0.0),
    );
  else
    return new MyGridView(allCities: _allCities);
}
Copy the code

So, the final UI is going to look like this

End of tutorial

Point of interest

Please read these articles carefully. It might give you a guide to what you really need:

  1. Material. IO/design/comp…
  2. Making: github.com/thatsalok/F…

Flutter tutorial

  1. Flutter Getting Started: Tutorial 1 Basics
  2. Flutter Getting Started: Tutorial 4 ListView

The Dart tutorials

  1. DART2 Prima Plus — Tutorial 1
  2. DART2 Prima Plus — Tutorial 2 — LIST
  3. DART2 Prima Plus — Tutorial 3 — MAP

history

  • 22-July-2018: First edition

If you find any errors in the translation or other areas that need improvement, you are welcome to revise and PR the translation in the Gold Translation program, and you can also get corresponding bonus points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.


Diggings translation project is a community for translating quality Internet technical articles from diggings English sharing articles. The content covers the fields of Android, iOS, front end, back end, blockchain, products, design, artificial intelligence and so on. For more high-quality translations, please keep paying attention to The Translation Project, official weibo and zhihu column.