配置问题
拉不下来阿里云镜像源,用浏览器访问网址明明可以下载下来,虽然警告可能会损坏计算机询问是否保留。通过百度,发现把之前配置的阿里云镜像地址的https
改成 http
就可以了。
maven { url 'http://maven.aliyun.com/repository/google' }
maven { url 'http://maven.aliyun.com/repository/jcenter' }
maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
序列化
import 'package:json_annotation/json_annotation.dart';
// user.g.dart 将在我们运行生成命令后自动生成
part 'user.g.dart';
///这个标注是告诉生成器,这个类是需要生成Model类的
@JsonSerializable()
class User{
User(this.name, this.email);
String name;
String email;
//不同的类使用不同的mixin即可
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}
一次性生成
通过在我们项目的根目录下运行flutter pub run build_runner build
命令,我们可以为模型生成JSON序列化代码。这个命令会触发一次性构建(one-time build),构建过程中会遍历源文件,选择需要生成JSON序列化代码的文件,为它们生成必要的序列化代码。
这种做法的优点是可以仅仅通过一条命令搞定代码的生成,缺点是如果我们这次生成完了代码,下次对Modek类进行了一点改动,那么原来生成的代码就不能用了,必须重新运行上述命令进行生成,难免有些麻烦。
持续生成
使用watcher可以使我们源代码的生成过程更加方便,它会监听我们项目中文件的变化,在必要时自动构建必要的文件。我们可以通过在项目根目录下运行flutter packages pub run build_runner watch
命令来启动watcher。这样我们只需启动一次watcher,他就会一直在在后台运行,不存在任何安全隐患。
redux
1. 如何使用 store 中的 state?
包一层 StoreBuilder<MyState>
就可以通过 store.state.
来调用
child: new StoreBuilder<MyState>(
builder: (context, store) {
User user = store.state.userInfo;
return new Drawer(
页面
1. topBar
1.1 左:
1.1.1 左侧是用户圆形头像,可以拉出侧边drawer
return new Scaffold(
appBar: new AppBar(
leading: new Container( // 左侧头像
padding: new EdgeInsets.all(3),
child: new ClipOval(
child: new Image.asset(
MyImages.DEFAULT_USER_AVATAR
),
),
修改 appBar 源码,联动 drawer 和 leading(注释的地方,需要修改两处)
Widget leading = widget.leading;
if (/* leading == null && */ widget.automaticallyImplyLeading) {
if (hasDrawer) {
leading = IconButton(
icon: /* const Icon(Icons.menu), */ leading ?? Icon(Icons.home),
1.1.2 二级页面(非首页)左侧 leading 自定义
AppBar 的 automaticallyImplyLeading 属性设置为false,为true时是返回图标。
child: new Scaffold(
appBar: new AppBar(
leading: appBar_leading,
automaticallyImplyLeading: false,
1.2 中:
1.2.1 中间标题 title 居中
new Scaffold(
appBar: new AppBar(
title: new Text(titles[_currentIndex]), // 中间的标题
centerTitle: true, // 标题居中
1.3 右:
1.3.1 appBar 右边的 按钮 自定义?
new Scaffold(
appBar: new AppBar(
actions: actions[_currentIndex], // 右侧控件
actions 列表,一个元素代表一个子页面对应的 appBar 右侧的 actions
// appBar右侧iconButton:appBar 用到
List<List<Widget>> actions = [
[
new IconButton(
icon: new Icon(Icons.search),
onPressed: () {},
)
],
1.4 其他:
1.3 二级页面(非首页),左侧 leading 自定义
2. Body
2.1 如何不让 pageView 左右滑动可以切换?
设置 physics
body: new PageView(
controller: _pageController,
children: tabPages,
physics: new NeverScrollableScrollPhysics(),
),
2.2 如何不让 TabBarView 左右滑动切换?
3. bottomBar
3.1 设置BottomNavigationBar超过3个后,不显示颜色
添加上属性
type: BottomNavigationBarType.fixed,
就能展示正常了
4. 事件
1. TabBar、TabBarView、TabController 联合使用,tab页面切换事件处理
使用了TabController,就不需要包DefaultTabController了
// controller 初始化
_tabController = new TabController(
initialIndex: 0,
length: _tabs.length,
vsync: this,
);
// 为 controller 添加监听
_tabController.addListener(_onTabChanged);
注意 .addListener(_onTabChanged())
是错误写法!!没有括号
_onTabChanged() {
// 按一次 tab 会触发两次 监听方法,两次的 _tabController.animation.value 值不同
// 一次是 开始位置,一次是 结束位置
if (_tabController.index.toDouble() == _tabController.animation.value) {
this.setState(() {
_currentIndex = _tabController.index;
});
}
}
图片
1. 显示圆形头像
new Container( // 左侧头像
padding: new EdgeInsets.all(3),
child: new ClipOval(
child: new Image.asset(
MyImages.DEFAULT_USER_AVATAR
),
),
路由
1. 跳转页面不加载动画效果