Flutter 入门实战 一

APP 导航框架与常用功能实现

APP 首页框架搭建

首先,先新建这些文件:
在这里插入图片描述
tab_navigator.dart 文件代码如下:

import 'package:flutter/material.dart';
import 'package:xiecheng/pages/home_page.dart';
import 'package:xiecheng/pages/my_page.dart';
import 'package:xiecheng/pages/search_page.dart';
import 'package:xiecheng/pages/travel_page.dart';

class TabNavigator extends StatefulWidget {
  @override
  _TabNavigatorState createState() => _TabNavigatorState();
}

class _TabNavigatorState extends State<TabNavigator> {
  final _defaultColor = Colors.grey;
  final _activeColor = Colors.blue;
  int _currentIndex = 0;
  final PageController _controller = PageController(
    initialPage: 0,
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageView(
        controller: _controller,
        children: [
          HomePage(),
          MyPage(),
          SearchPage(),
          TravelPage(),
        ],
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _currentIndex,
        onTap: (index) {
          _controller.jumpToPage(index);
          setState(() {
            _currentIndex = index;
          });
        },
        type: BottomNavigationBarType.fixed, //把lable进行固定
        items: [
          BottomNavigationBarItem(
            icon: Icon(
              Icons.home,
              color: _defaultColor,
            ),
            activeIcon: Icon(
              Icons.home,
              color: _activeColor,
            ),
            title: Text(
              '首页',
              style: TextStyle(
                color: _currentIndex != 0 ? _defaultColor : _activeColor,
              ),
            ),
          ),
          BottomNavigationBarItem(
            icon: Icon(
              Icons.search,
              color: _defaultColor,
            ),
            activeIcon: Icon(
              Icons.search,
              color: _activeColor,
            ),
            title: Text(
              '搜索',
              style: TextStyle(
                color: _currentIndex != 1 ? _defaultColor : _activeColor,
              ),
            ),
          ),
          BottomNavigationBarItem(
            icon: Icon(
              Icons.camera_alt,
              color: _defaultColor,
            ),
            activeIcon: Icon(
              Icons.camera_alt,
              color: _activeColor,
            ),
            title: Text(
              '旅拍',
              style: TextStyle(
                color: _currentIndex != 2 ? _defaultColor : _activeColor,
              ),
            ),
          ),
          BottomNavigationBarItem(
            icon: Icon(
              Icons.account_circle,
              color: _defaultColor,
            ),
            activeIcon: Icon(
              Icons.account_circle,
              color: _activeColor,
            ),
            title: Text(
              '我的',
              style: TextStyle(
                color: _currentIndex != 3 ? _defaultColor : _activeColor,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

home_page.dart 文件代码如下:

import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('首页'),
      ),
    );
  }
}

my_page.dart 文件代码如下:

import 'package:flutter/material.dart';

class MyPage extends StatefulWidget {
  @override
  _MyPageState createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('我的'),
      ),
    );
  }
}

search_page.dart 文件代码如下:

import 'package:flutter/material.dart';

class SearchPage extends StatefulWidget {
  @override
  _SearchPageState createState() => _SearchPageState();
}

class _SearchPageState extends State<SearchPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('搜索'),
      ),
    );
  }
}

travel_page.dart 文件代码如下:

import 'package:flutter/material.dart';

class TravelPage extends StatefulWidget {
  @override
  TravelPageState createState() => TravelPageState();
}

class TravelPageState extends State<TravelPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text('旅拍'),
      ),
    );
  }
}

最后将 main.dart 的代码进行微小的修改:
在这里插入图片描述
就可以运行啦:
在这里插入图片描述

轮播图 Banner 功能开发

轮播图需要用到的 swiper 插件,我们可以去 pub 网站上去找:
在这里插入图片描述
打开 pub 网站,搜索 swiper 即可:
在这里插入图片描述
这时候我们查看该插件的 Installing,里面会告诉你如何引入该插件:
在这里插入图片描述
这时候我们按照它说的步骤做就好啦:
在这里插入图片描述
引入后 VSCode 的右上角会出现一个下载的标志,点击下载即可;

然后编辑 home_page.dart 里的代码:

import 'package:flutter/material.dart';
import 'package:flutter_swiper/flutter_swiper.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List _imageUrls = [
    'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1976529436,2778459069&fm=26&gp=0.jpg',
    'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3597917999,2966077325&fm=26&gp=0.jpg',
    'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3352739916,685169444&fm=26&gp=0.jpg',
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: [
            Container(
              height: 160,
              child: Swiper(
                itemCount: _imageUrls.length,
                autoplay: true,
                itemBuilder: (BuildContext context, int index) {
                  return Image.network(
                    _imageUrls[index],
                    fit: BoxFit.fill,
                  );
                },
                pagination: SwiperPagination(),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

运行界面如下:
在这里插入图片描述

自定义 AppBar 实现滚动渐变

修改 home_page.dart 的代码,如下:

import 'package:flutter/material.dart';
import 'package:flutter_swiper/flutter_swiper.dart';

const APPBAR_SCROLL_OFFSET = 100; //设置滚动最大距离

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List _imageUrls = [
    'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1976529436,2778459069&fm=26&gp=0.jpg',
    'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3597917999,2966077325&fm=26&gp=0.jpg',
    'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3352739916,685169444&fm=26&gp=0.jpg',
  ];

  double appBarAlpha = 0.0;

  _onScroll(offset) {
    double alpha = offset / APPBAR_SCROLL_OFFSET;
    if (alpha < 0.0) {
      alpha = 0.0;
    } else if (alpha > 1.0) {
      alpha = 1.0;
    }
    setState(() {
      appBarAlpha = alpha;
    });
    // print(appBarAlpha);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          MediaQuery.removePadding(
            //把顶部预留的安全区域去掉
            removeTop: true,
            context: context,
            child: NotificationListener(
              //监听列表的滚动
              onNotification: (scrollNotification) {
                if (scrollNotification is ScrollUpdateNotification &&
                    scrollNotification.depth == 0) {
                  //滚动且是列表滚动的时候
                  _onScroll(scrollNotification.metrics.pixels);
                }
              },
              child: ListView(
                children: [
                  Container(
                    height: 160,
                    child: Swiper(
                      itemCount: _imageUrls.length,
                      autoplay: true,
                      itemBuilder: (BuildContext context, int index) {
                        return Image.network(
                          _imageUrls[index],
                          fit: BoxFit.fill,
                        );
                      },
                      pagination: SwiperPagination(),
                    ),
                  ),
                  Container(
                    height: 800,
                    child: ListTile(
                      title: Text('阿巴阿巴阿巴'),
                    ),
                  ),
                ],
              ),
            ),
          ),
          Opacity(
            //自定义AppBar
            opacity: appBarAlpha,
            child: Container(
              height: 80,
              decoration: BoxDecoration(color: Colors.white),
              child: Center(
                child: Padding(
                  padding: EdgeInsets.only(top: 20),
                  child: Text('首页'),
                ),
              ),
            ),
          )
        ],
      ),
    );
  }
}

运行界面:
在这里插入图片描述

网络编程与数据存储技术相关经验和技巧

基于Http实现网络操作

如何用 http 库做 get 请求?

  • pubspec.yaml 中引入 http 插件;
  • 调用 http.get 发送请求;
Future<http.Response> fetchPost() {
	return http.get('https://jsonplaceholder.typicode.com/posts/1');
}

http.get() 返回一个包含 http.ResponseFuture

  • Future:是与异步操作一起工作的核心 Dart 类。它用于表示未来某个时间可能会出现的可用值或错误;
  • http.Response:类包括一个成功的 HTTP 请求接收到的数据;

如何用 http 库做 post 请求?

  • pubspec.yaml 中引入 http 插件;
  • 调用 http.post 发送请求;
Future<http.Response> fetchPost() {
	return http.post('https://jsonplaceholder.typicode.com/posts/1');
}

http.post() 返回一个包含 http.ResponseFuture

  • Future:是与异步操作一起工作的核心 Dart 类。它用于表示未来某个时间可能会出现的可用值或错误;
  • http.Response:类包括一个成功的 HTTP 请求接收到的数据;

如何将 Response 转换成 Dart object?

虽然发出网络请求很简单,但如果要使用原始的 Future<http. Response> 并不简单。为了让我们可以开开心心的写代码,我们可以将 http.Response 转换成我们自己的 Dart 对象。

创建一个 CommonModel 类

首先,我们需要创建一个 CommonModel 类,它包含我们网络请求的数据。它还将包括一个工厂构造函数,它允许我们可以通过 json 创建个 CommonModel 对象。
在这里插入图片描述

将 http.Response 转换成一个 CommonModel 对象

在这里插入图片描述

如何将请求结果展示在界面上?

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

异步:Future 与 FutureBuilder 实用技巧

什么是 Future?

在这里插入图片描述

Future 的常见用法?

在这里插入图片描述

使用 future.then 获取 future 的值与捕获 future 的异常

在这里插入图片描述
在这里插入图片描述

结合 async await

在这里插入图片描述

future.whenComplete

在这里插入图片描述

future.timeout

在这里插入图片描述

什么是 FutureBuilder?

FutureBuilder 是一个将异步操作和异步 UI 更新结合在一起的类,通过它我们可以将网络请求,数据库读取等的结果更新的页面上。

FutureBuilder 的构造方法
FutureBuilder({Key key, Future<T> future, T initialData, @required AsyncWidgetBuilder<T> builder})

在这里插入图片描述
在这里插入图片描述

FutureBuilder 的使用?

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

JSON 解析与复杂模型转换实用技巧

应该是有哪种 JSON 序列化方式?

在这里插入图片描述

如何序列化?

在这里插入图片描述
在这里插入图片描述

复杂 JSON 解析?

如何解析对象中的数组?

在这里插入图片描述
解析:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

提示效率:在线转换 JSON TO Dart

基于 shared_preferences 本地存储操作

什么是 shared_preferences?

在这里插入图片描述

如何使用 shared_preferences?

在这里插入图片描述
在这里插入图片描述

shared_preferences 有哪些常用的 API?

存储相关

在这里插入图片描述

读取相关

在这里插入图片描述

基于 shared_preferences 实现计数器 Demo

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值