El primer ejemplo del sitio web oficial de Flutter

Enlace original

Prefacio

Al aprender Flutter, definitivamente verá el primer ejemplo en el sitio web oficial: chino  o  inglés . Pero como principiante, es posible que tenga dificultades para leerlo. El propósito de este artículo es ayudarlo a comprender mejor este ejemplo.

La representación final:

 

 

 

Primero analicemos cómo lograr el efecto en la figura anterior:

Desarrolladores de Android

1. Preparar datos: Los datos de lista y los datos seleccionados se pueden almacenar en dos listas o matrices respectivamente. 2. Lista de interfaz: use ListView o RecyclerView 3. Salto de interfaz: la intención se puede usar para llevar datos a una nueva página de lista

desarrollador de iOS

1. Preparar datos: los datos de la lista y los datos seleccionados se pueden almacenar en dos matrices respectivamente. 2. Lista de interfaces: use TableView o CollectionView 3. Salto de interfaz: use NavigationController, puede asignar valores directamente a nuevos objetos de página

En conclusión

Descubrimos que ya sea que se trate de un desarrollo nativo de Android o iOS, los pasos que deben realizarse son:

  1. Almacene los datos que se mostrarán, almacene los datos seleccionados
  2. Mostrar la lista y mostrar los datos
  3. Configurar para saltar a una nueva página

Entonces, en el desarrollo de Flutter, siga estos pasos para comprender mejor

Desarrollo de aleteo

* Preparar datos: los datos de la lista se almacenan en una matriz y los datos seleccionados se pueden almacenar en el conjunto (porque el conjunto puede eliminar automáticamente los duplicados). * Lista de interfaces: use ListView * Salto de interfaz: se puede usar Navigator

Desarme y analice el código oficial, lo llevará rápidamente a comprender

El sitio web oficial utiliza alrededor de 110 líneas de código para implementar el ejemplo anterior. Desmontamos estos códigos en tres partes principales para ayudarnos a aprender:

Requisito previo: primero debes usar Android Studio u otras herramientas de desarrollo para crear un proyecto de Flutter. Si necesitas aprender sobre este paso, puedes  aprender rápidamente aquí.

Cuando creas un nuevo proyecto de Flutter y lo ejecutas, el familiar "Hola mundo" aparecerá en la interfaz. Para entender el código de Flutter más fácilmente, analicemos primero el código de creación inicial, al menos para saber por dónde debemos comenzar:

 

 

 

Lo que queremos editar es el  archivo main.dart aquí  . Como otros idiomas, la función de entrada de Flutter es la función principal:

import 'package:flutter/material.dart';
 
void main() => runApp(new MyApp());   //分析 1
 
class MyApp extends StatelessWidget {  //分析 2 (StatelessWidget)
  @override
  Widget build(BuildContext context) {   //分析 3
    return new MaterialApp(
      title: 'Welcome to Flutter',
      home: new Scaffold(      //分析 4
        appBar: new AppBar(
          title: new Text('Welcome to Flutter'),
        ),
        body: new Center(  //分析 5
          child: new Text('Hello World'),
        ),
      ),
    );
  }
}

análisis

  1. Aquí  =>  es una abreviatura de la función de una línea en Dart, que es equivalente a:
void main() {
  runApp(new MyApp());
} 
  1. StatelessWidget representa un componente con un solo estado, que corresponde a StatefulWidget (lo que significa que puede haber varios estados). No es necesario profundizar en el principio aquí, solo sepa que esto está relacionado con la actualización de flutter, etc.

  2. En el componente Widget, el método de construcción se usa para describir su estructura interna. La compilación aquí significa que los componentes del sistema de MaterialApp se utilizan en la construcción de MyApp.

  3. El valor de la etiqueta de inicio: Scaffold es un componente proporcionado en la biblioteca de materiales, en el que podemos establecer la barra de navegación, el título y el atributo del cuerpo del árbol de widgets que contiene la pantalla de inicio. Puede ver aquí que AppBar y un texto se agregan a la página.

  4. El centro es un componente que puede colocar subcomponentes en el centro.

Empiece a remodelar

Nuestro objetivo es reemplazar el TextView que muestra hello_world en la página con un ListView. Del análisis anterior, podemos ver que reemplazar el valor de la etiqueta de inicio en el punto 4 anterior con un ListView puede cambiar el contenido que se muestra en la página. Pero antes de eso, necesitamos preparar los datos que se mostrarán. Aquí hay un  paquete tripartito llamado  english_words que puede ayudarnos a generar los datos de las palabras mostradas. Primero, aprenda a agregar paquetes dependientes:

 

 

 

  1. Abra el archivo pubspec.yaml para agregar una biblioteca de terceros:
dependencies:
  flutter:
    sdk: flutter
 
  cupertino_icons: ^0.1.0
  english_words: ^3.1.0
  1. Haga clic en  Paquetes para  obtener el paquete que acaba de agregar.

Después de agregar la biblioteca english_words, puede usar esta biblioteca para crear datos como este:

//创造5个随机词组,并返回词组的迭代器
generateWordPairs().take(5)

Aprenda a usar StatefulWidget

Al observar el código fuente de ListView, se encuentra que finalmente se hereda de StatelessWidget, por lo que su estado es único. Pero los datos en ListView que se implementarán cambian dinámicamente, por lo que debe usar StatefulWidget para cambiar dinámicamente los datos en ListView.

Para usar el componente StatefulWidget, debe controlar el estado de visualización en diferentes situaciones por sí mismo, por lo que debe implementar la clase State para decirle a la clase StatefulWidget cómo mostrarlo en diferentes situaciones.

Cree una clase de componente que cambie dinámicamente para representar el ListView que se mostrará:

class RandomWords extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {  //分析1
    return new RandomWordsState();
  }
}

análisis:

  1. El método de creación de la clase State, hereda aquí el estado del sistema para crear una clase llamada RandomWordsState para controlar la visualización en cada estado de ListView.
class RandomWordsState extends State<RandomWords> {
}
  1. 复制代码

Para completar los datos de visualización y guardar los datos en los que se hizo clic, use array y set to store respectivamente (use set para almacenar los datos en los que se hizo clic porque el set se puede deduplicar, también puede elegir otros métodos de almacenamiento)

class RandomWordsState extends State<RandomWords> {
  final _suggestions = <WordPair>[];   //分析 1
  final _saved = new Set<WordPair>();
  final _biggerFont = const TextStyle(fontSize: 18.0);   //分析 2
}

análisis:

  1. Agregue _ en Dart para indicar la privatización
  2. Constante para el tamaño de fuente

Crear conjunto de datos y construir ListView

Agregue los dos métodos siguientes a la clase RandomWordsState para representar la creación de un conjunto de datos y la construcción de un ListView:

Widget _buildSuggestions() {   
    return new ListView.builder(
      padding: const EdgeInsets.all(16.0),
      // 对于每个建议的单词对都会调用一次itemBuilder,然后将单词对添加到ListTile行中
      // 在偶数行,该函数会为单词对添加一个ListTile row.
      // 在奇数行,该函数会添加一个分割线widget,来分隔相邻的词对。
      // 注意,在小屏幕上,分割线看起来可能比较吃力。
      itemBuilder: (context, i) {          
        // 在每一列之前,添加一个1像素高的分隔线widget
        if (i.isOdd) return new Divider();
 
        // 语法 "i ~/ 2" 表示i除以2,但返回值是整形(向下取整),比如i为:1, 2, 3, 4, 5
        // 时,结果为0, 1, 1, 2, 2, 这可以计算出ListView中减去分隔线后的实际单词对数量
        final index = i ~/ 2;
        // 如果是建议列表中最后一个单词对
        if (index >= _suggestions.length) {
          // ...接着再生成10个单词对,然后添加到建议列表
          _suggestions.addAll(generateWordPairs().take(10));   
        }
        return _buildRow(_suggestions[index]);
      }
    );
  }
 
  Widget _buildRow(WordPair pair) {
    final alreadySaved = _saved.contains(pair);
 
    return new ListTile(
      title: new Text(
        pair.asPascalCase,
        style: _biggerFont,
      ),
      trailing: new Icon(
        alreadySaved ? Icons.favorite : Icons.favorite_border,
        color: alreadySaved ? Colors.red : null,
      ),
      onTap: () {
        setState(() {
          if (alreadySaved) {
            _saved.remove(pair);
          } else {
            _saved.add(pair);
          }
        });
      },
    );
  }

Hay comentarios detallados en el código, pero para facilitar la comprensión, aquí hay una pequeña explicación:

  1. El método _buildSuggestions es devolver un ListView
  2. El método _buildRow es devolver una fila en ListView (ListTile) cómo mostrar

En el método _buildSuggestions:

  • El itemBuilder en el código es cómo mostrar la configuración de una fila (ListTile), y su valor de retorno es el método _buildRow
  • _suggestions.addAll(generateWordPairs().take(10));Es agregar 10 datos a la matriz de visualización cada vez

En el método _buildRow:

  • Configurar una fila (ListTile representa una fila de contenido, llamada celda en iOS y Android) cómo mostrar
  • ListTile establece el título, al final (icono a la derecha) y haga clic en el evento enTap ()
  • Determinará qué icono mostrar a la derecha según se haya guardado
  • Cuando se hace clic, el contenido en el que no se ha hecho clic se guardará en el contenedor _saved.

Agregar lógica de salto

Agregue el método _pushSaved para indicar cómo saltar a una nueva página y mostrar los datos seleccionados:

main.dart

void _pushSaved() {
    Navigator.of(context).push(  // 分析 1
      new MaterialPageRoute(  // 分析 2
        builder: (context) {
          final tiles = _saved.map(  //数据
            (pair) {
              return new ListTile(
                title: new Text(
                  pair.asPascalCase,
                  style: _biggerFont,
                ),
              );
            },
          );
          final divided = ListTile.divideTiles(
            context: context,
            tiles: tiles,
          ).toList();
 
          return new Scaffold(  // 分析 3
            appBar: new AppBar(
              title: new Text('Saved Suggestions'),
            ),
            body: new ListView(children: divided),
          );
        },
      ),
    );
  }

Análisis: 1. Use Navigator.of (context) .push para manejar el salto, el parámetro requerido es una Ruta 2. Cree una página Ruta 3. Regrese a una nueva, el contenido del cuerpo dentro es un ListView, que se muestra Datos leer en _saved

Al final, toda la integración de código se ve así:

 
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
 
void main() => runApp(new MyApp());
 
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Welcome to Flutter',
      theme: new ThemeData(
        primaryColor: Colors.red,
      ),
      home: RandomWords(),
    );
  }
}
 
class RandomWords extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new RandomWordsState();
  }
}
 
class RandomWordsState extends State<RandomWords> {
  final _suggestions = <WordPair>[];
  final _saved = new Set<WordPair>();
  final _biggerFont = const TextStyle(fontSize: 18.0);
 
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Startup Name Generator'),
        actions: <Widget>[
          new IconButton(icon: new Icon(Icons.list), onPressed: _pushSaved),
        ],
      ),
      body: _buildSuggestions(),
    );
  }
 
  void _pushSaved() {
    Navigator.of(context).push(
      new MaterialPageRoute(
        builder: (context) {
          final tiles = _saved.map(
            (pair) {
              return new ListTile(
                title: new Text(
                  pair.asPascalCase,
                  style: _biggerFont,
                ),
              );
            },
          );
          final divided = ListTile.divideTiles(
            context: context,
            tiles: tiles,
          ).toList();
 
          return new Scaffold(
            appBar: new AppBar(
              title: new Text('Saved Suggestions'),
            ),
            body: new ListView(children: divided),
          );
        },
      ),
    );
  }
 
  Widget _buildSuggestions() {
    return new ListView.builder(
        padding: const EdgeInsets.all(16.0),
        itemBuilder: (context, i) {
          if (i.isOdd) return new Divider();
          final index = i ~/ 2;
          if (index >= _suggestions.length) {
            _suggestions.addAll(generateWordPairs().take(10));
          }
          return _buildRow(_suggestions[index]);
        });
  }
 
  Widget _buildRow(WordPair pair) {
    final alreadySaved = _saved.contains(pair);
 
    return new ListTile(
      title: new Text(
        pair.asPascalCase,
        style: _biggerFont,
      ),
      trailing: new Icon(
        alreadySaved ? Icons.favorite : Icons.favorite_border,
        color: alreadySaved ? Colors.red : null,
      ),
      onTap: () {
        setState(() {
          if (alreadySaved) {
            _saved.remove(pair);
          } else {
            _saved.add(pair);
          }
        });
      },
    );
  }
}

Ejecútelo, puede ver el efecto superior.

Supongo que te gusta

Origin blog.csdn.net/qq_41619796/article/details/114886840
Recomendado
Clasificación