zm.blog

select * from learn


  • 首页

  • 标签

  • 分类

  • 归档

  • 关于

  • 搜索

Flutter自定义TabBar

发表于 2020-03-14 | 分类于 Android , Flutter Tips | | 阅读次数:

custom_tabbar.dart

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import 'package:ajbaby/res/colors.dart';
import 'package:flutter/material.dart';


// ignore: must_be_immutable
class CustomTabBar extends StatefulWidget implements PreferredSizeWidget {
Color containerBgColor;
Color labelColor;
Color unselectedLabelColor;
Color indicatorColor;
TabController tabController;
List<Widget> tabsList = new List<Widget>();
List<Widget> tabBarViewsList = new List<Widget>();

// @required声明必传参数
CustomTabBar({
Key key,
@required this.tabsList,
@required this.tabBarViewsList,
@required this.tabController,
this.containerBgColor = YColors.color_FFFFFF,
this.labelColor = YColors.color_FF5F6D,
this.unselectedLabelColor = YColors.color_858585,
this.indicatorColor = YColors.color_FF5F6D,
}) : super(key: key);


@override
_CustomTabBarState createState() {
return _CustomTabBarState();
}


@override
// TODO: implement preferredSize
Size get preferredSize => null;
}


class _CustomTabBarState extends State<CustomTabBar> with AutomaticKeepAliveClientMixin {
@override
void initState() {
super.initState();
}


@override
void dispose() {
super.dispose();
// widget.tabController.dispose();
}


@override
Widget build(BuildContext context) {
super.build(context);
return Scaffold(
appBar: PreferredSize(
child: Container(
color: widget.containerBgColor,
child: TabBar(
isScrollable: true,
controller: widget.tabController,
tabs: widget.tabsList,
labelColor: widget.labelColor,
unselectedLabelColor: widget.unselectedLabelColor,
indicatorColor: widget.indicatorColor,
),
),
preferredSize: Size.fromHeight(kToolbarHeight)),
body: TabBarView(
controller: widget.tabController,
children: widget.tabBarViewsList,
),
);
}


@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
}

引用

1
2
3
4
5
body: CustomTabBar(
tabsList: _tabsList,
tabBarViewsList: _tabBarViewsList,
tabController: _tabController,
),
阅读全文 »

Flutter中管理路由栈的方法和应用

发表于 2020-03-12 | 分类于 Android , Flutter Tips | | 阅读次数:

本文首先讲的Flutter中的路由,然后主要讲下Flutter中栈管理的几种方法。

  • 了解下Route和Navigator
  • 简单的路由
  • 命名路由
  • 自定义路由
  • Flutter中使用的路由场景
  • Flutter中的路由栈管理
  • 实战

了解下Route和Navigator

在Flutter中,我们需要在不同屏幕或者页面之间进行切换和发送数据,这些“screens”或者“pages”被称为Route(路由),是由一个Navigator的小部件进行管理。

Navigator可以管理包含若干Route对象的堆栈,并提供了管理的方法,平常我们经常用的就是[Navigator.push]和[Navigator.pop]。

尽管我们可以自己直接创建一个navigator,但是当我们创建一个WidgetsApp或者MaterialApp,Flutter会自动默认创建一个Navigator。
所以我们一般是使用由[WidgetsApp]或者[MaterialApp]所创建的Navigator就行了,然后通过调用[Navigator.of]
来拿到当前的Navigator的状态NavigatorState,然后调用它的pop或者push方法。

简单的路由

比如要导航到一个新的页面,我们可以创建一个[MaterialPageRoute]的实例,然后调用Navigator.of(context).push()方法就将新页面添加到堆栈的顶部。

返回上一个页面,则调用Navigator.pop(context)就可以从堆栈中删除这个屏幕;

1
2
3
4
5
Navigator.of(context)
.push(new MaterialPageRoute(builder: (context) {
return new DetailPage();
}));
Navigator.pop(context);
阅读全文 »

Flutter自定义导航栏AppBar

发表于 2020-03-12 | 分类于 Android , Flutter Tips | | 阅读次数:

自定义AppBar

源码中可以看到,AppBar只是实现了 PreferredSizeWidget接口

1
class AppBar extends StatefulWidget implements PreferredSizeWidget

那么我们也可以从这进行入手,自定义一个实现了 PreferredSizeWidget的Widget
具体代码并不多,比你想象的简单,直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';

/// 这是一个可以指定SafeArea区域背景色的AppBar
/// PreferredSizeWidget提供指定高度的方法
/// 如果没有约束其高度,则会使用PreferredSizeWidget指定的高度

// ignore: must_be_immutable
class CustomAppbar extends StatefulWidget implements PreferredSizeWidget {
final double contentHeight; //从外部指定高度
Color navigationBarBackgroundColor; //设置导航栏背景的颜色
Widget leadingWidget;
Widget trailingWidget;
String title;

CustomAppbar({
@required this.leadingWidget,
@required this.title,
this.contentHeight = 44,
this.navigationBarBackgroundColor = Colors.white,
this.trailingWidget,
}) : super();

@override
State<StatefulWidget> createState() {
return new _CustomAppbarState();
}

@override
Size get preferredSize => new Size.fromHeight(contentHeight);
}

/// 这里没有直接用SafeArea,而是用Container包装了一层
/// 因为直接用SafeArea,会把顶部的statusBar区域留出空白
/// 外层Container会填充SafeArea,指定外层Container背景色也会覆盖原来SafeArea的颜色
/// var statusheight = MediaQuery.of(context).padding.top; 获取状态栏高度

class _CustomAppbarState extends State<CustomAppbar> {
@override
void initState() {
super.initState();
}

@override
Widget build(BuildContext context) {
return new Container(
color: widget.navigationBarBackgroundColor,
child: new SafeArea(
top: true,
child: new Container(
decoration: new UnderlineTabIndicator(
borderSide: BorderSide(width: 1.0, color: Color(0xFFeeeeee)),
),
height: widget.contentHeight,
child: new Stack(
alignment: Alignment.center,
children: <Widget>[
Positioned(
left: 0,
child: new Container(
padding: const EdgeInsets.only(left: 5),
child: widget.leadingWidget,
),
),
new Container(
child: new Text(
widget.title,
style: new TextStyle(
fontSize: ScreenUtil().setSp(33, allowFontScalingSelf: true),
color: Color(0xFF333333),
fontWeight: FontWeight.w600),
),
),
Positioned(
right: 0,
child: new Container(
padding: const EdgeInsets.only(right: 5),
child: widget.trailingWidget,
),
),
],
)),
),
);
}
}

引用的地方:

1
2
3
4
5
appBar: new CustomAppbar(
title: '日历',
leadingWidget: leftBarButtonItemWidget(),
trailingWidget: rightBarButtonItemsWidget(),
)

leftBarButtonItemWidget() rightBarButtonItemsWidget()两个方法是我自定义的导航栏按钮,实现自己需要的即可。值得说的是,可以将leadingWidget设置为非@required的,在自定义的AppBar里面做好处理即可,另外在上面的代码中并没有限制导航栏上每个Widget所占用的最大空间,如果你的导航栏子组件可能很宽,提前进行妥善处理是个好主意。

阅读全文 »

flutter屏幕适配方案

发表于 2020-03-12 | 分类于 Android , Flutter Tips | | 阅读次数:

flutter_ScreenUtil

pub package

flutter 屏幕适配方案,让你的UI在不同尺寸的屏幕上都能显示合理的布局!

github: https://github.com/OpenFlutter/flutter_screenutil

使用方法:

安装依赖:

安装之前请查看最新版本

1
2
3
4
5
dependencies:
flutter:
sdk: flutter
# 添加依赖
flutter_screenutil: ^1.0.2

在每个使用的地方导入包:

1
import 'package:flutter_screenutil/flutter_screenutil.dart';

属性

属性 类型 默认值 描述
width double 1080px 设计稿中设备的宽度,单位px
height double 1920px 设计稿中设备的高度,单位px
allowFontScaling bool false 设置字体大小是否根据系统的“字体大小”辅助选项来进行缩放
阅读全文 »

Flutter_BottomNavigationBar切换页面防止页面重绘

发表于 2020-03-10 | 分类于 Android , Flutter Tips | | 阅读次数:

开始尝试用flutter开发,flutter版本1.0,写类似微信底部tab切换界面时发现界面老被重置,网上找了一圈说保持状态需要子页面mixin AutomaticKeepAliveClientMixin,然后重写

1
2
@override
bool get wantKeepAlive => true;

但发现需要配合其他组件,不是随便mixin就有用的,尝试几种写法总结BottomNavigationBar+List+AutomaticKeepAliveClientMixin是没有用的

  1. 首先尝试BottomNavigationBar+List实现的页面切换保持状态,一般刚开始学都会这么写:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) => MaterialApp(
title: "demo",
home: MainPage(),
);
}

class MainPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => MainPageState();
}

class MainPageState extends State<MainPage> {
int _currentIndex;
List<Widget> _pages;

@override
void initState() {
super.initState();
_currentIndex = 0;
_pages = List()..add(FirstPage("第一页"))..add(SecondPage("第二页"))..add(ThirdPage("第三页"));
}

@override
Widget build(BuildContext context) => Scaffold(
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
items: getItems(),
currentIndex: _currentIndex,
onTap: onTap,
),
);

List<BottomNavigationBarItem> getItems() {
return [
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text("Home")),
BottomNavigationBarItem(icon: Icon(Icons.adb), title: Text("Adb")),
BottomNavigationBarItem(icon: Icon(Icons.person), title: Text("Person"))
];
}

void onTap(int index) {
setState(() {
_currentIndex = index;
});
}
}
阅读全文 »

Flutter_tabBarView切换页面防止页面重绘

发表于 2020-03-10 | 分类于 Android , Flutter Tips | | 阅读次数:

被重绘的tab页要 混入AutomaticKeepAliveClientMixin

1
2
// with 混入
class DevicePageLayout extends WidgetState<DevicePage> with AutomaticKeepAliveClientMixin

实现wantKeepAlive方法 ,返回值改成true

1
2
3
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;

build中加入 super.build(context);

1
2
3
4
@override
Widget build(BuildContext context) {
super.build(context);
// TODO: implement build
阅读全文 »

Android Studio 3.6 正式版终于发布了

发表于 2020-03-04 | 分类于 Android , Android Tips | | 阅读次数:

如题,Android Studio 3.6 正式版终于发布了,值得兴奋呀,毕竟 3.5 大版本更新也已经差不多半年了,撒花撒花!这次更新又更新了什么呢?

包括有设计、开发、构建、测试、优化等多方面,下面我们来看看 Release Notes 写了些什么吧!

Release Notes

我们很高兴宣布 Android Studio 3.6 发布稳定版本了,该版本内有一些针对性的新特性,主要解决了在代码编辑和调试用例中的质量问题。这是我们在 Project Marble 结束之后的第一个版本,其重点是构建强大的集成开发环境(IDE)的基本功能和流。我们从 Project Marble 中学到了很多,在 Android Studio 3.6 中,我们引入了一小部分功能,完善的现有功能,并花费了很大的精力来解决错误并改善基础性能,以确保我们达到去年设定的高质量标准。

Android Studio 3.6 的一些亮点包括一种使用 XML 快速设计、开发和预览应用布局的新方法,在设计编辑器中提供了新的拆分视图。此外,您不再需要手动键入 GPS 坐标来测试应用的位置,因为我们现在将 Google 地图直接嵌入到 Android 模拟器扩展控制面板中。最后,通过针对片段和活动的自动内存泄漏检测,我们简化了应用并查找 Bug。我们希望所有这些功能可以帮助您在 Android 上开发时更快乐、更高效。

感谢在预览版中提供早期反馈的用户。您的反馈帮助我们迭代和改进 Android Studio 3.6 中的功能。如果您已准备好迎接下一个稳定版本,并且想要使用一组新的生产力功能,Android Studio 3.6 已准备好下载,以便您入门。

以下是 Android Studio 3.6 中由主要开发人员流组织的全部新功能列表。

阅读全文 »

Flutter不能热加载,热重载按钮为灰色

发表于 2020-03-03 | 分类于 Android , Flutter | | 阅读次数:

前言,Flutter的热重载(hot reload)功能可以帮助您在无需重新启动应用的情况下快速、轻松地进行测试、构建用户界面、添加功能以及修复错误。

通过将更新后的源代码文件注入正在运行的Dart虚拟机(VM)中来实现热重载。

在虚拟机使用新的的字段和函数更新类后,Flutter框架会自动重新构建widget树,以便您快速查看更改的效果。

要热重载一个Flutter应用程序:

  1. 从受支持的IntelliJ IDE 、Android Studio 或终端窗口运行应用程序。物理机或虚拟器都可以运行。
  2. 修改项目中的一个Dart文件。大多数类型的代码更改可以重新加载; 有关需要完全重新启动的更改列表,请参阅限制。
  3. 如果您使用的是IntelliJ IDE 、Android Studio ,请选择Save All (cmd-s/ctrl-s)),或者单击工具栏上的Hot Reload按钮。
阅读全文 »

SourceTree_push_remote:Invalid_username_or_password.

发表于 2020-02-27 | 分类于 Android , Android Tips | | 阅读次数:

在网络里面移除就行了· 再推就会要你重新输入了。
有点不人性化, mark 一下。

阅读全文 »

一文读懂 Android Debug 调试

发表于 2020-02-27 | 分类于 Android , Android Tips | | 阅读次数:

一、打上断点,启动debug模式

首先在我们需要打断点的代码行数上稍微偏右,点击鼠标左键,如图:

点击小爬虫按钮,启动debug模式。

运行成功后如下。可以看到红色框内,从下往上的顺序运行方法,一直阻塞在我们打断点的方法里;绿色款内,则是展示目前阻塞方法内变量和参数的数值。

阅读全文 »
1…678…38
ZhangMiao

ZhangMiao

Android/Flutter Developer

379 日志
58 分类
143 标签
RSS
E-Mail QQ Github StackOverflow
友情链接
  • Kaisir
  • Liujianhui
  • Leo
  • Hongyang
  • Liuwangshu
  • Jspang
  • Blankj
  • WuXiaoLong
  • Molunerfinn
  • Ofind
  • Gcssloop
© 2024 ZhangMiao
由 Hexo 强力驱动
|
主题 — NexT.Gemini v5.1.4
本站访客数 人次 本站总访问量 次