提交 bbc3d000 authored 作者: Kevin's avatar Kevin

优化了WeuiToast的效果,添加了WeuiToastConfig,可以全局配置默认设置

添加了Keyboard对android 返回按钮的监听
上级 1de6edba
## [0.2.0]
* TODO: 优化了WeuiToast的效果,添加了WeuiToastConfig,可以全局配置默认设置
* TODO: 添加了Keyboard对android 返回按钮的监听
## [0.1.16]
* Updated SDK constraint to support new error message formats
* Updated error message formats
......
......@@ -9,7 +9,7 @@ Usage Add this to your package's pubspec.yaml file:
Flutter >=1.7
``` yaml
dependencies:
cool_ui: "^0.1.16"
cool_ui: "^0.2.0"
```
Flutter < 1.7
......
......@@ -6,16 +6,18 @@ VoidCallback showWeuiToast({
@required BuildContext context,
@required Widget message,
@required Widget icon,
Alignment alignment = const Alignment(0.0,-0.2),
RouteTransitionsBuilder transitionBuilder})
bool stopEvent = false,
Alignment alignment,
bool backButtonClose})
```
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| [context] | <code>BuildContext<Widget></code> | | 上下文 |
| [message] | <code>Widget<Widget></code> | | 提示消息 |
| [alignment] | <code>Alignment<Widget></code>| 默认是居中偏上 | Toast的位置 |
| [icon] | <code>Widget<Widget></code> | | 图标 |
| [transitionBuilder] | <code>RouteTransitionsBuilder<Widget></code> | | 自定义过度动画 |
| [context] | <code>BuildContext</code> | | 上下文 |
| [message] | <code>Widget</code> | | 提示消息 |
| [icon] | <code>Widget</code> | | 图标 |
| [stopEvent] | <code>bool</code> | false | 阻止父页面事件触发 |
| [alignment] | <code>Alignment</code>| 默认是居中偏上 | Toast的位置 |
| [backButtonClose] | <code>bool</code> | | 安卓返回按钮是否关闭Toast |
返回参数:VoidCallback,用于关闭Toast
......@@ -27,19 +29,21 @@ VoidCallback showWeuiToast({
```dart
Future showWeuiSuccessToast({
@required BuildContext context,
@required Widget message=const Text("成功"),
Alignment alignment = const Alignment(0.0,-0.2),
RouteTransitionsBuilder transitionBuilder,
Duration closeDuration = const Duration(seconds: 3)
Widget message,
bool stopEvent,
bool backButtonClose,
Alignment alignment,
Duration closeDuration
})
```
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| [context] | <code>BuildContext<Widget></code> | | 上下文 |
| [transitionBuilder] | <code>RouteTransitionsBuilder<Widget></code> | | 自定义过度动画 |
| [alignment] | <code>Alignment<Widget></code>| 默认是居中偏上 | Toast的位置 |
| [message] | <code>Widget<Widget></code> | 成功| 提示消息 |
| [closeDuration] | <code>Duration<Widget></code> | 3s | 关闭时间 |
| [context] | <code>BuildContext</code> | | 上下文 |
| [alignment] | <code>Alignment</code>| 默认是居中偏上 | Toast的位置 |
| [message] | <code>Widget</code> | 成功| 提示消息 |
| [stopEvent] | <code>bool</code> | false | 阻止父页面事件触发 |
| [closeDuration] | <code>Duration</code> | 3s | 关闭时间 |
| [backButtonClose] | <code>bool</code> | true | 安卓返回按钮是否关闭Toast |
返回参数:Future dart 异步操作,代表Toast已关闭
......@@ -49,16 +53,72 @@ Future showWeuiSuccessToast({
```dart
VoidCallback showWeuiToast({
@required BuildContext context,
@required Widget message,
Alignment alignment = const Alignment(0.0,-0.2),
RouteTransitionsBuilder transitionBuilder
Widget message,
stopEvent = true,
bool backButtonClose,
Alignment alignment
})
```
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| [context] | <code>BuildContext<Widget></code> | | 上下文 |
| [message] | <code>Widget<Widget></code> | | 提示消息 |
| [alignment] | <code>Alignment<Widget></code>| 默认是居中偏上 | Toast的位置 |
| [transitionBuilder] | <code>RouteTransitionsBuilder<Widget></code> | | 自定义过度动画 |
| [stopEvent] | <code>bool</code> | true | 阻止父页面事件触发 |
| [backButtonClose] | <code>bool</code> | false | 安卓返回按钮是否关闭Toast |
| [alignment] | <code>Alignment</code>| 默认是居中偏上 | Toast的位置 |
返回参数:VoidCallback,用于关闭Toast
## WeuiToastConfigData
设置默认Toast效果
```dart
const WeuiToastConfigData({this.successText = '成功',
this.successDuration = const Duration(seconds: 3),
this.successBackButtonClose = true,
this.loadingText = '加载中',
this.loadingBackButtonClose = false,
this.toastAlignment = const Alignment(0.0, -0.2)});
```
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| [successText] | <code>String</code> | 成功 | 成功提示消息 |
| [successDuration] | <code>Duration</code> |3s | 成功Toast关闭事件 |
| [successBackButtonClose] | <code>bool</code> | true | 成功安卓返回按钮是否关闭Toast |
| [loadingText] | <code>String</code> | 加载中 | 加载中提示消息 |
| [loadingBackButtonClose] | <code>false</code> | true | 加载中安卓返回按钮是否关闭Toast |
| [alignment] | <code>Alignment</code>| 默认是居中偏上 | Toast的位置 |
## WeuiToastConfig
设置默认Toast效果 配合WeuiToastConfigData使用
```dart
WeuiToastConfig({Widget child,this.data})
```
| Param | Type | Default | Description |
| --- | --- | --- | --- |
| [child] | <code>Widget</code> | | Widget |
| [data] | <code>WeuiToastConfigData</code> | | Toast配置数据 |
在Widget中添加了WeuiToastConfig,然后子Widget的context就可以应用到效果了
例如:
```dart
main.dart
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return WeuiToastConfig( // --关键代码
data: WeuiToastConfigData( // --关键代码
successText: '测试ConfigData' // --关键代码
), // --关键代码
child:MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue
),
home: MyHomePage(title: 'Flutter Demo Home Page')
));
}
}
```
代表全局默认配置
......@@ -16,7 +16,11 @@ class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
return WeuiToastConfig(
data: WeuiToastConfigData(
successText: '测试ConfigData'
),
child:MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
......@@ -30,7 +34,7 @@ class MyApp extends StatelessWidget {
primarySwatch: Colors.blue
),
home: MyHomePage(title: 'Flutter Demo Home Page')
);
));
}
}
......@@ -74,7 +78,7 @@ class _MyHomePageState extends State<MyHomePage> {
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
......
......@@ -28,7 +28,7 @@ class CustomKeyboardDemoState extends State<CustomKeyboardDemo>{
body: ListView(
children: <Widget>[
TextField(
keyboardType: TextInputType.text,
keyboardType: NumberKeyboard.inputType,
),
Container(
height: 300.0,
......
......@@ -30,13 +30,13 @@ class WeuiToastDemoState extends State<WeuiToastDemo>{
color: Colors.blue[400],
child: Text("成功",style: TextStyle(color: Colors.white),),
onPressed: ()=>showWeuiSuccessToast(context:context,message: Text("成功啦!")),
onPressed: ()=>showWeuiSuccessToast(context:context),
),
RaisedButton(
color: Colors.blue[400],
child: Text("加载中",style: TextStyle(color: Colors.white),),
onPressed: (){
var hide = showWeuiLoadingToast(context:context, message:Text("加载中"));
var hide = showWeuiLoadingToast(context:context);
Future.delayed(Duration(seconds: 5),(){
hide();
});
......
......@@ -4,6 +4,7 @@ import 'dart:async';
import 'dart:ui' as ui;
import 'dart:core';
import 'package:back_button_interceptor/back_button_interceptor.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
......
part of cool_ui;
typedef HideCallback = Future Function();
class WeuiToast extends TransitionRoute{
OverlayEntry _toastBarrier;
final Widget message;
final Widget icon;
final RouteTransitionsBuilder _transitionBuilder;
final Duration closeDuration;
final Alignment alignment;
WeuiToast({
@required this.message,
class WeuiToastWidget extends StatelessWidget {
const WeuiToastWidget({
Key key,
@required this.stopEvent,
@required this.alignment,
@required this.icon,
this.alignment = const Alignment(0.0,-0.2),
Duration transitionDuration = const Duration(milliseconds: 100),
RouteTransitionsBuilder transitionBuilder,
this.closeDuration
}):assert(icon != null),
assert(message!=null),
_transitionDuration = transitionDuration,
_transitionBuilder = transitionBuilder;
@override
void didChangePrevious(Route<dynamic> previousRoute) {
super.didChangePrevious(previousRoute);
changedInternalState();
}
@override
void changedInternalState() {
super.changedInternalState();
_toastBarrier.markNeedsBuild();
}
@override
Iterable<OverlayEntry> createOverlayEntries() sync* {
yield _toastBarrier = OverlayEntry(builder: _buildToastBarrier);
yield OverlayEntry(builder: _buildToastScope, maintainState: true);
}
@required this.message,
}) : super(key: key);
// TODO: implement opaque
@override
bool get opaque => false;
final bool stopEvent;
final Alignment alignment;
final Widget icon;
final Widget message;
// TODO: implement transitionDuration
@override
Duration get transitionDuration => _transitionDuration;
final Duration _transitionDuration;
Widget _buildToastBarrier(BuildContext context){
return IgnorePointer(
ignoring: true,
);
}
Widget _buildToastScope(BuildContext context){
return Material(
Widget build(BuildContext context) {
var widget = Material(
color: Colors.transparent,
child: Align(
alignment: this.alignment,
child: IntrinsicHeight(
child: AnimatedBuilder(
animation: animation,
builder: (context,child){
return _buildTransition(context,animation,secondaryAnimation,child);
},
child: Container(
width: 122.0,
decoration: BoxDecoration(
color: Color.fromRGBO(17, 17, 17, 0.7),
borderRadius: BorderRadius.circular(5.0)
),
constraints: BoxConstraints(
minHeight: 122.0,
alignment: this.alignment,
child: IntrinsicHeight(
child: Container(
width: 122.0,
decoration: BoxDecoration(
color: Color.fromRGBO(17, 17, 17, 0.7),
borderRadius: BorderRadius.circular(5.0)),
constraints: BoxConstraints(
minHeight: 122.0,
),
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 22.0),
constraints: BoxConstraints(minHeight: 55.0),
child: IconTheme(
data: IconThemeData(color: Colors.white, size: 55.0),
child: icon),
),
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 22.0),
constraints:BoxConstraints(
minHeight: 55.0
) ,
child: IconTheme(data: IconThemeData(color: Colors.white,size: 55.0), child: icon),
),
DefaultTextStyle(
style: TextStyle(
color: Colors.white,
fontSize: 16.0
),
child: message,
),
],
DefaultTextStyle(
style: TextStyle(color: Colors.white, fontSize: 16.0),
child: message,
),
),
],
),
),
)
),
),
);
return IgnorePointer(
ignoring: !stopEvent,
child: widget,
);
}
Widget _buildTransition( BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child){
if (_transitionBuilder == null) {
return FadeTransition(
opacity: CurvedAnimation(
parent: animation,
curve: Curves.linear,
),
child: child);
} // Some default transition
return _transitionBuilder(context, animation, secondaryAnimation, child);
}
}
Future showWeuiSuccessToast({
@required BuildContext context,
Widget message=const Text("成功"),
RouteTransitionsBuilder transitionBuilder,
Alignment alignment = const Alignment(0.0,-0.2),
Duration closeDuration = const Duration(seconds: 3)
}){
var hide = showWeuiToast(
context: context,
alignment: alignment,
message: message,
icon: Icon(CoolUIIcons.success_no_circle),
transitionBuilder:transitionBuilder);
return Future.delayed(closeDuration,(){
hide();
});
}
HideCallback showWeuiLoadingToast({
@required BuildContext context,
@required Widget message,
Alignment alignment = const Alignment(0.0,-0.2),
RouteTransitionsBuilder transitionBuilder
}){
return showWeuiToast(
context: context,
alignment: alignment,
message: message,
icon: WeuiLoadingIcon(),
transitionBuilder:transitionBuilder);
}
HideCallback showWeuiToast({
@required BuildContext context,
@required Widget message,
@required Widget icon,
Alignment alignment = const Alignment(0.0,-0.2),
RouteTransitionsBuilder transitionBuilder}){
Completer<VoidCallback> result = Completer<VoidCallback>();
Navigator.of(context,rootNavigator: true).push(
WeuiToast(
alignment: alignment,
message: Builder(builder: (context){
if(!result.isCompleted){
result.complete(()=>Navigator.pop(context));
}
return message;
}),
icon: icon,
transitionBuilder:transitionBuilder));
return () async{
var hide = await result.future;
hide();
};
}
class WeuiLoadingIcon extends StatefulWidget{
class WeuiLoadingIcon extends StatefulWidget {
final double size;
WeuiLoadingIcon({this.size = 50.0});
@override
State<StatefulWidget> createState() => WeuiLoadingIconState();
}
class WeuiLoadingIconState extends State<WeuiLoadingIcon>
with SingleTickerProviderStateMixin
{
with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation<double> _doubleAnimation;
......@@ -201,11 +77,10 @@ class WeuiLoadingIconState extends State<WeuiLoadingIcon>
_controller = new AnimationController(
vsync: this, duration: Duration(milliseconds: 1000))
..repeat();
_doubleAnimation= Tween(begin: 0.0,end: 360.0).animate(_controller)..addListener((){
setState(() {
_doubleAnimation = Tween(begin: 0.0, end: 360.0).animate(_controller)
..addListener(() {
setState(() {});
});
});
}
@override
......@@ -218,11 +93,156 @@ class WeuiLoadingIconState extends State<WeuiLoadingIcon>
@override
Widget build(BuildContext context) {
return Transform.rotate(
angle: _doubleAnimation.value ~/ 30 * 30.0 * 0.0174533,
child: Image.asset("assets/images/loading.png",
package: "cool_ui",
width: widget.size,
height: widget.size)
angle: _doubleAnimation.value ~/ 30 * 30.0 * 0.0174533,
child: Image.asset("assets/images/loading.png",
package: "cool_ui", width: widget.size, height: widget.size));
}
}
@immutable
class WeuiToastConfigData{
final String successText;
final Duration successDuration;
final bool successBackButtonClose;
final String loadingText;
final bool loadingBackButtonClose;
final Alignment toastAlignment;
const WeuiToastConfigData({this.successText = '成功',
this.successDuration = const Duration(seconds: 3),
this.successBackButtonClose = true,
this.loadingText = '加载中',
this.loadingBackButtonClose = false,
this.toastAlignment = const Alignment(0.0, -0.2)});
copyWith({String successText,Duration successDuration,String loadingText,Alignment toastAlignment}){
return WeuiToastConfigData(
successText: successText ?? this.successText,
successDuration: successDuration ?? this.successDuration,
loadingText: loadingText ?? this.loadingText,
toastAlignment: toastAlignment ?? this.toastAlignment
);
}
}
\ No newline at end of file
}
class WeuiToastConfig extends InheritedWidget{
final WeuiToastConfigData data;
WeuiToastConfig({Widget child,this.data}): super(child:child);
@override
bool updateShouldNotify(WeuiToastConfig oldWidget) {
// TODO: implement updateShouldNotify
return data != oldWidget.data;
}
static WeuiToastConfigData of(BuildContext context) {
var widget = context.inheritFromWidgetOfExactType(WeuiToastConfig);
if(widget is WeuiToastConfig){
return widget.data;
}
return WeuiToastConfigData();
}
}
Future showWeuiSuccessToast(
{@required BuildContext context,
Widget message,
stopEvent = false,
bool backButtonClose,
Alignment alignment,
Duration closeDuration}) {
var config = WeuiToastConfig.of(context);
message = message?? Text(config.successText);
closeDuration = closeDuration?? config.successDuration;
backButtonClose = backButtonClose ?? config.successBackButtonClose;
var hide = showWeuiToast(
context: context,
alignment: alignment,
message: message,
stopEvent: stopEvent,
backButtonClose: backButtonClose,
icon: Icon(CoolUIIcons.success_no_circle));
return Future.delayed(closeDuration, () {
hide();
});
}
HideCallback showWeuiLoadingToast(
{@required BuildContext context,
Widget message,
stopEvent = true,
bool backButtonClose,
Alignment alignment}) {
var config = WeuiToastConfig.of(context);
message = message?? Text(config.loadingText);
backButtonClose = backButtonClose ?? config.loadingBackButtonClose;
return showWeuiToast(
context: context,
alignment: alignment,
message: message,
stopEvent: stopEvent,
icon: WeuiLoadingIcon(),
backButtonClose: backButtonClose);
}
int backButtonIndex = 2;
HideCallback showWeuiToast(
{@required BuildContext context,
@required Widget message,
@required Widget icon,
bool stopEvent = false,
Alignment alignment,
bool backButtonClose}) {
var config = WeuiToastConfig.of(context);
alignment = alignment?? config.toastAlignment;
Completer<VoidCallback> result = Completer<VoidCallback>();
var backButtonName = 'CoolUI_WeuiToast$backButtonIndex';
BackButtonInterceptor.add((stopDefaultButtonEvent){
print(backButtonClose);
if(backButtonClose){
result.future.then((hide){
hide();
});
}
return true;
}, zIndex: backButtonIndex, name: backButtonName);
backButtonIndex++;
var overlay = OverlayEntry(
maintainState: true,
builder: (_) => WillPopScope(
onWillPop: () async {
var hide = await result.future;
hide();
return false;
},
child: WeuiToastWidget(
alignment: alignment,
icon: icon,
message: message,
stopEvent: stopEvent,
),
));
result.complete((){
if(overlay == null){
return;
}
overlay.remove();
overlay = null;
BackButtonInterceptor.removeByName(backButtonName);
});
Overlay.of(context).insert(overlay);
return () async {
var hide = await result.future;
hide();
};
}
......@@ -27,7 +27,7 @@ class CoolKeyboard {
if(isInterceptor)
return;
isInterceptor = true;
BinaryMessages.setMockMessageHandler("flutter/textinput", (ByteData data) async{
defaultBinaryMessenger.setMockMessageHandler("flutter/textinput", (ByteData data) async{
var methodCall = _codec.decodeMethodCall(data);
switch(methodCall.method){
case 'TextInput.show':
......@@ -69,7 +69,7 @@ class CoolKeyboard {
var callbackMethodCall = MethodCall("TextInputClient.updateEditingState",[
_keyboardController.client.connectionId,
_keyboardController.value.toJSON()]);
BinaryMessages.handlePlatformMessage("flutter/textinput", _codec.encodeMethodCall(callbackMethodCall), (data){
defaultBinaryMessenger.handlePlatformMessage("flutter/textinput", _codec.encodeMethodCall(callbackMethodCall), (data){
});
});
......@@ -135,9 +135,15 @@ class CoolKeyboard {
});
Overlay.of(_context).insert(_keyboardEntry);
BackButtonInterceptor.add((_){
CoolKeyboard.sendPerformAction(TextInputAction.done);
return true;
}, zIndex: 1, name:'CustomKeyboard');
}
static hideKeyboard({bool animation=true}){
BackButtonInterceptor.removeByName('CustomKeyboard');
if(_keyboardEntry != null && _pageKey != null) {
_keyboardHeight = null;
_pageKey.currentState.animationController.addStatusListener((AnimationStatus status) {
......@@ -178,7 +184,7 @@ class CoolKeyboard {
_keyboardController.client.connectionId,
action.toString()
]);
BinaryMessages.handlePlatformMessage(
defaultBinaryMessenger.handlePlatformMessage(
"flutter/textinput", _codec.encodeMethodCall(callbackMethodCall), (
data) {});
}
......
# Generated by pub
# See https://www.dartlang.org/tools/pub/glossary#lockfile
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
......@@ -7,7 +7,14 @@ packages:
name: async
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.8"
version: "2.2.0"
back_button_interceptor:
dependency: "direct main"
description:
name: back_button_interceptor
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.0.6"
boolean_selector:
dependency: transitive
description:
......@@ -45,7 +52,7 @@ packages:
name: matcher
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.12.3+1"
version: "0.12.5"
meta:
dependency: transitive
description:
......@@ -60,13 +67,20 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.6.2"
pedantic:
dependency: transitive
description:
name: pedantic
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.7.0"
quiver:
dependency: transitive
description:
name: quiver
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.1"
version: "2.0.3"
sky_engine:
dependency: transitive
description: flutter
......@@ -78,7 +92,7 @@ packages:
name: source_span
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.4.1"
version: "1.5.5"
stack_trace:
dependency: transitive
description:
......@@ -92,7 +106,7 @@ packages:
name: stream_channel
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.6.8"
version: "2.0.0"
string_scanner:
dependency: transitive
description:
......@@ -106,14 +120,14 @@ packages:
name: term_glyph
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.1"
version: "1.1.0"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.2.1"
version: "0.2.5"
typed_data:
dependency: transitive
description:
......@@ -129,4 +143,5 @@ packages:
source: hosted
version: "2.0.8"
sdks:
dart: ">=2.0.0 <3.0.0"
dart: ">=2.2.2 <3.0.0"
flutter: ">=1.7.0 <2.0.0"
name: cool_ui
description: Some practical Widget for flutter,Popover,Weui,Custom Keyboard
version: 0.1.16
version: 0.2.0
author: Kevin <liangkaikevin@gmail.com>
homepage: https://github.com/Im-Kevin/cool_ui
......@@ -9,6 +9,7 @@ environment:
flutter: ">=1.7.0 <2.0.0"
dependencies:
back_button_interceptor: ^4.0.6
flutter:
sdk: flutter
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论