flutter 创建第一个应用

本文作者也是初学者,因此所有的知识都是来自这里

如何创建第一个应用

  • 启动 VS Code
  • 调用 View>Command Palette…
  • 输入 ‘flutter’, 然后选择 ‘Flutter: New Project’ action
  • 输入 Project 名称 (如myapp), 然后按回车键
  • 指定放置项目的位置,然后按蓝色的确定按钮
  • 等待项目创建继续,并显示main.dart文件

运行应用程序

  • 确保在VS Code的右下角选择了目标设备
  • 按 F5 键或调用Debug>Start Debugging
  • 等待应用程序启动
  • 如果一切正常,在应用程序建成功后,您应该在您的设备或模拟器上看到应用程序:(作为ios程序我使用的是iphone 模拟器)


体验热重载技术

我们将main.dart 文件的所有内容替换成如下

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Welcome to Flutter',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Welcome to Flutter'),
        ),
        body: new Center(
          child: new Text('Hello World'),
        ),
      ),
    );
  }
}

按键command+ s, 屏幕就显示如下了


这样极大的方便了我们的开发

第一个小工程介绍以及类比

分析以上代码

  • 本示例创建一个Material APP。Material是一种标准的移动端和web端的视觉设计语言。 Flutter提供了一套丰富的Material widgets。

  • main函数使用了(=>)符号, 这是Dart中单行函数或方法的简写。

  • 该应用程序继承了 StatelessWidget,这将会使应用本身也成为一个widget。 在Flutter中,大多数东西都是widget,包括对齐(alignment)、填充(padding)和布局(layout)

  • Scaffold 是 Material library 中提供的一个widget, 它提供了默认的导航栏、标题和包含主屏幕widget树的body属性。widget树可以很复杂。

  • widget的主要工作是提供一个build()方法来描述如何根据其他较低级别的widget来显示自己。

  • 本示例中的body的widget树中包含了一个Center widget, Center widget又包含一个 Text 子widget。 Center widget可以将其子widget树对其到屏幕中心。

包管理

我们可以 在pub.dartlang.org上找到english_words软件包以及其他许多开源软件包

  • pubspec文件管理Flutter应用程序的assets(资源,如图片、package等)。 在pubspec.yaml中,将english_words(3.1.0或更高版本)添加到依赖项列表,如下面高亮显示的行:
dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^0.1.0
  english_words: ^3.1.0

pubspec.yaml 在save(Command+s)的时候加载english_words依赖包

这里注意 english_words: ^3.1.0 一定要与cupertino_icons: ^0.1.0 首字母对齐,要不程序是报错的

导入包

在main.dart 文件中头上加入

import 'package:english_words/english_words.dart';

相当于引用该包

注意,我们刚引入的时候,该行是灰色的,有警告,说明没有使用该包

使用该包,将main.dart 修改成如下

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) {
    final wordPair = new WordPair.random();
    return new MaterialApp(
      title: 'Welcome to Flutter',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Welcome to Flutter'),
        ),
        body: new Center(
          //child: new Text('Hello World'),
          child: new Text(wordPair.asPascalCase),
        ),
      ),
    );
  }
}

结果运行


添加一个 有状态的部件(Stateful widget)

Stateless widgets 是不可变的, 这意味着它们的属性不能改变 - 所有的值都是最终的.

Stateful widgets 持有的状态可能在widget生命周期中发生变化. 实现一个 stateful widget 至少需要两个类:

  • 一个 StatefulWidget类。
  • 一个 State类。 StatefulWidget类本身是不变的,但是 State类在widget生命周期中始终存在.

这里只贴上最终代码,主要是分析这段代码的含义

// Step 3 - Add a stateful widget

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',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Welcome to Flutter'),
        ),
        body: new Center(
          child: new RandomWords(),
        ),
      ),
    );
  }
}

class RandomWords extends StatefulWidget {
  @override
  createState() => new RandomWordsState();
}

class RandomWordsState extends State<RandomWords> {
  @override
  Widget build(BuildContext context) {
    final wordPair = new WordPair.random();
    return (new Text(wordPair.asPascalCase));
  }
}

这段代码运行的结果


image.png

理解什么叫有状态的部件(Stateful widget)
我的理解就body->child 的内容可以动态变化的。
可以理解为固定 和可变。
要是我们将child 的值设置成固定的值,这将不能改变,我猜测这里可能是因为我们没有办法在重新拿到myApp对象。
因此我们想让child的值改变,只能对child的值进行引用,进行改变。
这里对该值进行引用使用的是StatefulWidget 类。
该类使用只需要时重写方法createState 方法即可。

创建无限循环listView

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',
      home: new RandomWords(),
    );
  }
}

class RandomWords extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return new RandomWordState();
  }
}
class  RandomWordState extends State<RandomWords> {
  final _suggestions = <WordPair>[];
  final _biggerFont = const TextStyle(fontSize: 18.0);

   Widget _buildRow(WordPair pair){
      return new ListTile(
        title: new Text(
          pair.asPascalCase,
          style: _biggerFont,
        ),
      );
    }

  Widget _buildSuggestions(){
    return new ListView.builder(
      padding: const EdgeInsets.all(16.0),
      itemBuilder: (context,i){
        if (i.isOdd) {
          return new Divider();
        }
       final index = i~/1;
       if (index >=_suggestions.length) {
         _suggestions.addAll(generateWordPairs().take(10));
       }
       return _buildRow(_suggestions[index]);
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("startup Name generator"),
      ),
    body: _buildSuggestions(),
    );
  }
}

这里只是贴下代码
这里其实只是讲解了下listview的具体使用。这里不做介绍,后面会详细学习

添加交互

如何给listView的Item添加事件呢很简单如下

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',
      home: new RandomWords(),
    );
  }
}

class RandomWords extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return new RandomWordState();
  }
}
class  RandomWordState extends State<RandomWords> {
  final _suggestions = <WordPair>[];
  final _biggerFont = const TextStyle(fontSize: 18.0);
  final _saved = new Set<WordPair>();
   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);
            }
          });
        },
      );
      
    }

  Widget _buildSuggestions(){
    return new ListView.builder(
      padding: const EdgeInsets.all(16.0),
      itemBuilder: (context,i){
        if (i.isOdd) {
          return new Divider();
        }
       final index = i~/1;
       if (index >=_suggestions.length) {
         _suggestions.addAll(generateWordPairs().take(10));
       }
       return _buildRow(_suggestions[index]);
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("startup Name generator"),
      ),
    body: _buildSuggestions(),
    );
  }
}

导航

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',
      home: new RandomWords(),
    );
  }
}

class RandomWords extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return new RandomWordState();
  }
}
class  RandomWordState extends State<RandomWords> {
  final _suggestions = <WordPair>[];
  final _biggerFont = const TextStyle(fontSize: 18.0);
  final _saved = new Set<WordPair>();
  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 _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);
            }
          });
        },
      );
      
    }

  Widget _buildSuggestions(){
    return new ListView.builder(
      padding: const EdgeInsets.all(16.0),
      itemBuilder: (context,i){
        if (i.isOdd) {
          return new Divider();
        }
       final index = i~/1;
       if (index >=_suggestions.length) {
         _suggestions.addAll(generateWordPairs().take(10));
       }
       return _buildRow(_suggestions[index]);
      },
    );
  }

  @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(),
      
    );
  
  }
}
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容