flutter学习集合
文章集合flutter学习实战详解: 地址flutter 各种实例demo例子 地址
·
文章集合
- flutter学习实战详解: 地址
- flutter 各种实例demo例子 地址
- dio 网络请求封装 地址
- flutter 轮播图 地址
- flutter 下拉刷新,上拉加载 地址
- flutter | 老孟 各个组件使用方法和第三方开源库介绍
- flutetr 获取app版本信息 地址
- flutter 加载动画 flutter_spinkit
- flutter 代码规范 地址
- json直接转换为model类 json_model
- flutter App升级 1、后台管理地址 github集成地址 2、集成具体操作
- flutter 对接微信登录、支付 地址
- flutter使用svg 地址
- flutter loading使用 文档地址、 github地址
- 直接点击onTap调用alertDialog 地址
- flutter使用全局状态管理Providere地址
- **flutter监听键盘是否弹出 地址
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text('你确定要这样做吗?'),
actions: <Widget>[
new FlatButton(
child: new Text('取消'),
onPressed: () {
Navigator.of(context).pop(); // 取消返回
print('取消');
},
),
new FlatButton(
child: new Text('确定'),
onPressed: () {
Navigator.of(context).pop();
print('确定');
},
)
],
);
}
);
- flutter蒙文排版布局
// vertical-font.dart
import 'package:ZyFlutter/utils/hex_color.dart';
import 'package:flutter/material.dart';
class VerticalFont extends StatelessWidget {
// 标题
final String title;
// 字体大小
final double fontSize;
// 字体颜色
final String color;
VerticalFont({this.title, this.fontSize = 20.0, this.color = '#000000'});
@override
Widget build(BuildContext context) {
return RotatedBox(
quarterTurns: 1,
child: RichText(
text: TextSpan(
text: title,
style: TextStyle(
fontFamily: 'mn',
fontSize: this.fontSize,
color: HexColor(color))),
),
);
}
}
- flutter顶部tabs创建(方式一,在title上创建)
- 使用StatefulWidget和自行构造TabController实现
/*
* @Description:
* @version:
* @Author: 周凯
* @Date: 2020-06-16 21:38:15
* @LastEditors: 周凯
* @LastEditTime: 2020-07-25 19:27:49
*/
// 下面代码将TabBar放到了AppBar的title上。
import 'package:flutter/material.dart';
/// 短视屏页面
class ShortVideo extends StatefulWidget {
@override
_ShortVideoState createState() => _ShortVideoState();
}
class _ShortVideoState extends State<ShortVideo>
with SingleTickerProviderStateMixin {
TabController tabController;
@override
void initState() {
super.initState();
tabController = TabController(length: 2, vsync: this);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: TabBar(
tabs: [
Tab(
icon: Icon(Icons.directions_car),
text: "短视频",
),
Tab(
icon: Icon(Icons.directions_bike),
text: "其他",
),
],
controller: tabController,
),
),
body: TabBarView(
children: [
Center(child: Text('汽车')),
Center(child: Text('自行车')),
],
controller: tabController,
),
);
}
@override
void dispose() {
super.dispose();
tabController.dispose();
}
}
- flutter顶部tabs创建(方式二)
- 使用DefaultTabController来实现简单的tab效果:
class TopTabPage1 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text('交通工具'),
bottom: TabBar(tabs: [
Tab(
icon: Icon(Icons.directions_car),
text: "汽车",
),
Tab(
icon: Icon(Icons.directions_bike),
text: "自行车",
),
Tab(
icon: Icon(Icons.directions_boat),
text: '轮船',
),
]),
),
body: TabBarView(children: [
Center(child: Text('汽车')),
Center(child: Text('自行车')),
Center(child: Text('轮船')),
]),
),
);
}
}
- **flutter顶部tabs创建(方式三)
/*
* @Description:
* @version:
* @Author: 周凯
* @Date: 2020-06-16 21:38:15
* @LastEditors: 周凯
* @LastEditTime: 2020-07-26 15:32:50
*/
import 'dart:async';
import 'package:ZyFlutter/pages/home/live_video_list.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'
as extended;
/// NestedScrollView示例页面
class NestedScrollViewPage extends StatefulWidget {
@override
NestedScrollViewPageState createState() {
return NestedScrollViewPageState();
}
}
class NestedScrollViewPageState extends State<NestedScrollViewPage>
with SingleTickerProviderStateMixin {
// 滚动控制器
ScrollController _scrollController;
// Tab控制器
TabController _tabController;
int _tabIndex = 0;
// 列表
int _listCount = 20;
// 表格
int _gridCount = 30;
// 初始化
@override
void initState() {
super.initState();
_tabController = TabController(length: 2, vsync: this);
_scrollController = ScrollController();
}
@override
void dispose() {
super.dispose();
_tabController.dispose();
_scrollController.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: extended.NestedScrollView(
pinnedHeaderSliverHeightBuilder: () {
return MediaQuery.of(context).padding.top + kToolbarHeight;
},
innerScrollPositionKeyBuilder: () {
if (_tabController.index == 0) {
return Key('Tab0');
} else {
return Key('Tab1');
}
},
headerSliverBuilder: (context, innerBoxIsScrolled) {
return <Widget>[
new SliverAppBar(
title: new PreferredSize(
child: new Card(
color: Theme.of(context).primaryColor,
elevation: 0.0,
margin: new EdgeInsets.all(0.0),
shape: new RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(0.0)),
),
child: new TabBar(
controller: _tabController,
onTap: (index) {
setState(() {
_tabIndex = index;
});
},
tabs: <Widget>[
new Tab(
text: '短视频',
),
new Tab(
text: '直播',
),
],
),
),
preferredSize: new Size(double.infinity, 46.0),
),
),
];
},
body: IndexedStack(
index: _tabIndex,
children: <Widget>[
extended.NestedScrollViewInnerScrollPositionKeyWidget(
Key('Tab0'),
EasyRefresh(
child: ListView.builder(
padding: EdgeInsets.all(0.0),
itemBuilder: (context, index) {
return SampleListItem();
},
itemCount: _listCount,
),
onRefresh: () async {
await Future.delayed(Duration(seconds: 2), () {
if (mounted) {
setState(() {
_listCount = 20;
});
}
});
},
onLoad: () async {
await Future.delayed(Duration(seconds: 2), () {
if (mounted) {
setState(() {
_listCount += 10;
});
}
});
},
),
),
extended.NestedScrollViewInnerScrollPositionKeyWidget(
Key('Tab1'),
EasyRefresh(
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 6 / 7,
),
itemBuilder: (context, index) {
return SampleListItem(
direction: Axis.horizontal,
);
},
itemCount: _gridCount,
),
onRefresh: () async {
await Future.delayed(Duration(seconds: 2), () {
if (mounted) {
setState(() {
_gridCount = 30;
});
}
});
},
onLoad: () async {
await Future.delayed(Duration(seconds: 2), () {
if (mounted) {
setState(() {
_gridCount += 10;
});
}
});
},
),
),
],
),
),
);
}
}
//pages/home/live_video_list.dart
import 'package:flutter/material.dart';
import 'package:ZyFlutter/utils/hex_color.dart';
import 'package:ZyFlutter/routes/application.dart';
/// 简单列表项
class SampleListItem extends StatelessWidget {
/// 方向
final Axis direction;
/// 宽度
final double width;
/// 右侧颜色
// 红色
final String defaultRightRed = '#00FF3A';
// 绿色
final String defaultRightGreen = '#00FF3A';
// 蓝色
final String defaultRightBlue = '#0008FF';
const SampleListItem(
{Key key, this.direction = Axis.vertical, this.width = double.infinity})
: super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
_goToDetails(context);
},
child: Container(
padding: EdgeInsets.only(top: 10.0, right: 10.0, bottom: 0, left: 10.0),
height: 112.0,
color: Theme.of(context).backgroundColor,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(children: <Widget>[
// 左侧价钱
topText('%3', Theme.of(context).textSelectionColor,
Theme.of(context).backgroundColor, 14.0, 0, 14.0, 0),
// 左侧清晰度
topText('HD', Theme.of(context).textSelectionColor,
Theme.of(context).backgroundColor, 2, 0, 2, 0, 10.0)
]),
// 右侧
topText('测试123123', HexColor(defaultRightBlue),
HexColor('#ffffff'), 14.0, 0, 14.0, 0),
],
),
),
Text(
'直播播放标题---------------------------------',
textAlign: TextAlign.start,
style: TextStyle(color: HexColor('#ffffff')),
),
Container(
width: double.infinity,
margin: EdgeInsets.only(top: 8.0),
padding: EdgeInsets.only(bottom: 8.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: HexColor('#222222'), width: 1.0),
),
),
child: Text(
'2020/05/16 10:00 - 05/18 12:00',
style: TextStyle(
color: HexColor('#ffffff'),
),
),
)
],
),
),
);
}
}
/// 跳转详情页面
void _goToDetails(BuildContext context) {
Application.router.navigateTo(context, '/detail?id=3');
}
/// 列表顶部小部件
Widget topText(String title, Color boxcolor, Color textColor, double left,
double top, double right, double bottom,
[double marginLeft = 0]) {
return Container(
decoration: BoxDecoration(
color: boxcolor,
borderRadius: BorderRadius.all(Radius.circular(2.0)),
),
margin: EdgeInsets.only(left: marginLeft),
padding:
EdgeInsets.only(left: left, top: top, right: right, bottom: bottom),
child: Text(
title,
style: TextStyle(
color: textColor,
),
),
);
}
- flutter使用dio网络库请求 异常跳转路由 获取context
- main.dart 添加全局的key
- 原文: 地址
// main.dar
final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 路由注入全局使用
final router = Router();
Routes.configureRoutes(router);
Application.router = router;
// 结束
return Container(
child: FlutterEasyLoading(
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: '测试app',
// 添加的全局key
navigatorKey: navigatorKey,
),
),
);
}
}
// 路由跳转
navigatorKey.currentState.pushNamed('/login');
- flutter实现沉浸式导航
### 我们只需要在生命周期 initState()或者其他的钩子中调用下面的 方法即可
/// 状态栏样式 沉浸式状态栏
_statusBar([String color]) {
// 白色沉浸式状态栏颜色 白色文字
SystemUiOverlayStyle light = SystemUiOverlayStyle(
systemNavigationBarColor: Color(0xFF000000),
systemNavigationBarDividerColor: null,
/// 注意安卓要想实现沉浸式的状态栏 需要底部设置透明色
statusBarColor: Colors.transparent,
systemNavigationBarIconBrightness: Brightness.light,
statusBarIconBrightness: Brightness.light,
statusBarBrightness: Brightness.dark,
);
// 黑色沉浸式状态栏颜色 黑色文字
SystemUiOverlayStyle dark = SystemUiOverlayStyle(
systemNavigationBarColor: Color(0xFF000000),
systemNavigationBarDividerColor: null,
/// 注意安卓要想实现沉浸式的状态栏 需要底部设置透明色
statusBarColor: Colors.transparent,
systemNavigationBarIconBrightness: Brightness.light,
statusBarIconBrightness: Brightness.dark,
statusBarBrightness: Brightness.light,
);
// 这个地方你可以去掉三目运算符 直接调用你想要的 效果即可
"while" == color?.trim()
? SystemChrome.setSystemUIOverlayStyle(light)
: SystemChrome.setSystemUIOverlayStyle(dark);
}
flutter报错整合
- flutter运行报错
FAILURE: Build failed with an exception.
* What went wrong:
Could not determine the dependencies of task ':app:compileDebugJavaWithJavac'.
> Could not resolve all task dependencies for configuration ':app:debugCompileClasspath'.
> Could not resolve io.flutter:flutter_embedding_debug:1.0.0-540786dd51f112885a89792d678296b95e6622e5.
Required by:
project :app
> Skipped due to earlier error
> Skipped due to earlier error
> Skipped due to earlier error
> Skipped due to earlier error
> Could not resolve io.flutter:x86_debug:1.0.0-540786dd51f112885a89792d678296b95e6622e5.
Required by:
project :app
> Skipped due to earlier error
> Skipped due to earlier error
> Skipped due to earlier error
> Skipped due to earlier error
> Could not resolve io.flutter:x86_64_debug:1.0.0-540786dd51f112885a89792d678296b95e6622e5.
Required by:
project :app
> Skipped due to earlier error
> Skipped due to earlier error
> Skipped due to earlier error
> Skipped due to earlier error
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 1m 48s
- 解决方案:[地址](https://www.jianshu.com/p/93d06d1bbf37)
- flutter 打包release网络请求无法使用
- 解决方案: 我第一次也是加到android/src/profile/AndroidManifest.xml不生效 真机上图片都加载不出来,查看应用信息显示没有申请任何权限,
稍后看了一下,和profile同级的main目录下还有一个AndroidManifest.xml文件,即android/src/main/AndroidManifest.xml使用权限申请配置放到这里 打包再次安装 就可以访问网路了。
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
- 使用flutter_ijkplayer插件打包release闪退
- 解决方案: 在 proguard 文件加入下面内容,参考地址: 地址
-keep class tv.danmaku.ijk.media.player.** {*;}
flutter_bugly和open_file使用lib冲突
- open_file readme 地址
- 解决方案: 在 /android/app/src/main/AndroidManifest.xml添加
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" // 添加+++
package="xxx.xxx.xxxxx">
<application>
...
// 添加+++
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileProvider"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths"
tools:replace="android:resource" />
</provider>
// 结束+++
</application>
</manifest>
更多推荐


所有评论(0)