1. Android中实现消息推送、指定设备推送
第三方包: jpush_flutter
实例:
import 'package:flutter/material.dart';
import 'package:jpush_flutter/jpush_flutter.dart';
class ExamplePage extends StatefulWidget {
Map arguments;
ExamplePage({Key key, this.arguments}) : super(key: key);
@override
_ExamplePageState createState() =>
_ExamplePageState(arguments: this.arguments);
}
class _ExamplePageState extends State<ExamplePage> {
Map arguments;
_ExamplePageState({this.arguments});
@override
void initState() {
super.initState();
this.initJpush();
}
// 监听极光推送
initJpush() {
JPush jpush = new JPush();
jpush.setup(
appKey: '20fa4b7bb897ee829a8f0e18',
channel: 'theChannel',
production: false,
debug: false
);
// 设置别名,用于指定设备推送
jpush.setAlias('wq123').then((map){
print('设置别名成功$map');
});
jpush.addEventHandler(
// 接受通知回调方法
onReceiveNotification: (Map<String,dynamic> message) async {
print("接受通知回调方法 $message");
},
// 点击通知回调方法
onOpenNotification: (Map<String,dynamic> message) async {
print("点击通知回调方法 $message");
},
// 接受自定义消息回调方法
onReceiveMessage: (Map<String,dynamic> message) async {
print("接受自定义消息回调方法 $message");
}
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('极光推送'),
),
body: Center(
child: Column(),
) // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
2. Flutter国际化 、升级Flutter Sdk
(1)找到 pubspec.yaml 配置 flutter_localizations
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
(2)main.dart 中导入国际化的包 flutter_localizations
import 'package:flutter_localizations/flutter_localizations.dart';
(3)设置国际化
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import './Example.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ExamplePage(),
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate
],
supportedLocales: [
const Locale('zh', 'CH'),
const Locale('en', 'US'),
]
);
}
}
链接:https://segmentfault.com/a/1190000018773751
3. 及时通信
第三方库: socket_io_client
import 'package:flutter/material.dart';
import 'package:socket_io_client/socket_io_client.dart';
class ExamplePage extends StatefulWidget {
Map arguments;
ExamplePage({Key key, this.arguments}) : super(key: key);
@override
_ExamplePageState createState() =>
_ExamplePageState(arguments: this.arguments);
}
class _ExamplePageState extends State<ExamplePage> {
Map arguments;
Socket socket;
List messageList = [];
ScrollController scrollController = new ScrollController();
_ExamplePageState({this.arguments});
@override
void initState() {
super.initState();
this.connectServer();
}
connectServer() {
socket = io('http://192.168.124.25:8000', <String, dynamic>{
'transports': ['websocket'],
'autoConnect': true,
'extraHeaders': {'foo': 'bar'} // optional
});
socket.on('connect', (_){
print('connect');
socket.emit('toServer','已经连接上了....');
});
socket.on('toClient', (data){
setState(() {
this.messageList.add(data);
this.scrollController.jumpTo(this.scrollController.position.maxScrollExtent+30);
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('及时通信'),
),
body: Center(
child: Column(
children: <Widget>[
Container(
height: 400,
child: ListView.builder(
controller: this.scrollController,
itemCount: this.messageList.length,
itemBuilder: (context,index){
return ListTile(
title: Text(this.messageList[index]),
);
}
),
),
RaisedButton(
child: Text('发送消息'),
onPressed: (){
this.socket.emit('toServer','帅不?');
},
),
],
),
) // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
4. 流媒体在线直播
直播主要通过两步实现:1.推流 2.拉流
推流:指的是把采集阶段封包好的内容传输到服务器的过程。推流的设备可以是计算机也可以是摄像头或者手机
拉流:指服务器已有直播内容,用指定地址进行拉取播放的过程
第三方库:flutter_ijkplayer
示例:
import 'package:flutter/material.dart';
import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
class ExamplePage extends StatefulWidget {
Map arguments;
ExamplePage({Key key, this.arguments}) : super(key: key);
@override
_ExamplePageState createState() =>
_ExamplePageState(arguments: this.arguments);
}
class _ExamplePageState extends State<ExamplePage> {
Map arguments;
IjkMediaController controller = IjkMediaController();
_ExamplePageState({this.arguments});
@override
void initState() {
super.initState();
this.initMedia();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
initMedia() async {
await controller.setNetworkDataSource(
'https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4',
autoPlay: false
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('流媒体'),
),
body: ListView(
children: <Widget>[
Container(
height: 200, // 这里随意
child: IjkPlayer(
mediaController: controller,
),
)
],
) // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
5. 指纹识别认证
第三方库: local_auth
实例:
import 'package:flutter/material.dart';
import 'package:local_auth/local_auth.dart';
import 'package:local_auth/auth_strings.dart';
class ExamplePage extends StatefulWidget {
Map arguments;
ExamplePage({Key key, this.arguments}) : super(key: key);
@override
_ExamplePageState createState() =>
_ExamplePageState(arguments: this.arguments);
}
class _ExamplePageState extends State<ExamplePage> {
Map arguments;
_ExamplePageState({this.arguments});
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
LocalAuthentication localAuth = LocalAuthentication();
return Scaffold(
appBar: AppBar(
title: Text('指纹识别'),
),
body: ListView(
children: <Widget>[
RaisedButton(
child: Text('检测是否支持生物识别'),
onPressed: () async{
bool canCheckBiometrics = await localAuth.canCheckBiometrics;
print("canCheckBiometrics $canCheckBiometrics");
},
),
RaisedButton(
child: Text('获取支持的生物识别列表'),
onPressed: () async{
List<BiometricType> availableBiometrics = await localAuth.getAvailableBiometrics();
print("availableBiometrics $availableBiometrics");
},
),
RaisedButton(
child: Text('指纹生物认证'),
onPressed: () async{
const andStrings = const AndroidAuthMessages(
cancelButton: '取消',
goToSettingsButton: '去设置',
fingerprintNotRecognized: '指纹识别失败',
goToSettingsDescription: '请设置指纹.',
fingerprintHint: '指纹',
fingerprintSuccess: '指纹识别成功',
signInTitle: '指纹验证',
fingerprintRequiredTitle: '请先录入指纹!',
);
bool didAuthenticate = await localAuth.authenticateWithBiometrics(
localizedReason: '扫描指纹进行验证',
useErrorDialogs: false,
stickyAuth: true,
androidAuthStrings :andStrings
);
print("didAuthenticate $didAuthenticate");
},
)
],
) // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
6.Flutter 底部 Tab 切换保持页面状态的几种 方法
(1)IndexedStack用法:
Container(
width: double.infinity,
height: double.infinity,
child: new IndexedStack(
index: 0,
alignment: Alignment.center,
children: <Widget>[
Image.network("https://www.itying.com/images/flutter/list1.jpg",fit: BoxFit.cover,),
Image.network("https://www.itying.com/images/flutter/list2.jpg",fit: BoxFit.cover)
])
)
(2)AutomaticKeepAliveClientMixin用法
import 'package:flutter/material.dart';
import '../../pages/Home/view.dart';
import '../../pages/Category/view.dart';
import '../../pages/Cart/view.dart';
import '../../pages/User/view.dart';
class Tabs extends StatefulWidget {
@override
_TabsState createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
List bottomItems = [
{
"icon": Icon(Icons.home),
"title": Text('首页'),
},
{
"icon": Icon(Icons.category),
"title": Text('分类'),
},
{
"icon": Icon(Icons.shopping_cart),
"title": Text('购物车'),
},
{
"icon": Icon(Icons.people),
"title": Text('我的'),
},
];
List<Widget> pageList = [
Home(),
Category(),
Cart(),
User()
];
getBottomItems () {
return bottomItems.map((item){
return BottomNavigationBarItem(
icon: item['icon'],
title: item['title']
);
}).toList();
}
int currentIndex = 1;
PageController pageController;
@override
void initState() {
super.initState();
this.pageController = PageController(initialPage: this.currentIndex);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("京东商城"),
),
body: PageView(
controller: this.pageController,
children: pageList,
onPageChanged: (index){
this.setState((){
this.currentIndex = index;
});
},
),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
fixedColor: Colors.red,
currentIndex: this.currentIndex,
onTap: (index) {
this.setState((){
this.currentIndex = index;
this.pageController.jumpToPage(this.currentIndex);
});
},
// 禁止PageView左右滑动
physics: NeverScrollableScrollPhysics(),
items: getBottomItems(),
),
);
}
}
// 需要在页面中继承AutomaticKeepAliveClientMixin
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin{
@override bool get wantKeepAlive => true;
}