diff --git a/flutter_app_upgrade/android/build.gradle b/flutter_app_upgrade/android/build.gradle index d5372c6..1e8d205 100644 --- a/flutter_app_upgrade/android/build.gradle +++ b/flutter_app_upgrade/android/build.gradle @@ -21,18 +21,35 @@ rootProject.allprojects { } } +def dartEnvironmentVariables = [ + // 是否是Google Play版, Google Play禁止App从第三方升级, 此时需要禁用掉插件中相关功能 + // 可用通过gradle.properties配置该属性的默认值, 若不配置, 默认为false + flutter_app_upgrade_googlePlay: project.findProperty('flutter_app_upgrade_googlePlayDefaultValue') ?: 'false', +] +if (project.hasProperty('dart-defines')) { + dartEnvironmentVariables += project.property('dart-defines').split(',').collectEntries { + // def pair = new String(Base64.decoder.decode(it)).split('=') + def pair = URLDecoder.decode(it).split('=') + [(pair.first()): pair.last()] + } +} + apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { - compileSdkVersion 28 + compileSdkVersion 31 sourceSets { - main.java.srcDirs += 'src/main/kotlin' + main { + java.srcDirs += 'src/main/kotlin' + manifest.srcFile Boolean.parseBoolean(dartEnvironmentVariables.flutter_app_upgrade_googlePlay) ? 'src/google/AndroidManifest.xml' : 'src/main/AndroidManifest.xml' + } } defaultConfig { minSdkVersion 16 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + buildConfigField 'boolean', 'googlePlay', dartEnvironmentVariables.flutter_app_upgrade_googlePlay } lintOptions { disable 'InvalidPackage' diff --git a/flutter_app_upgrade/android/src/google/AndroidManifest.xml b/flutter_app_upgrade/android/src/google/AndroidManifest.xml new file mode 100644 index 0000000..d14dac4 --- /dev/null +++ b/flutter_app_upgrade/android/src/google/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + diff --git a/flutter_app_upgrade/android/src/main/AndroidManifest.xml b/flutter_app_upgrade/android/src/main/AndroidManifest.xml index 536432d..73baed8 100644 --- a/flutter_app_upgrade/android/src/main/AndroidManifest.xml +++ b/flutter_app_upgrade/android/src/main/AndroidManifest.xml @@ -2,4 +2,6 @@ package="com.flutter.flutter_app_upgrade"> + + diff --git a/flutter_app_upgrade/android/src/main/kotlin/com/flutter/flutter_app_upgrade/FlutterAppUpgradePlugin.kt b/flutter_app_upgrade/android/src/main/kotlin/com/flutter/flutter_app_upgrade/FlutterAppUpgradePlugin.kt index 2241ed1..5b6f9fc 100644 --- a/flutter_app_upgrade/android/src/main/kotlin/com/flutter/flutter_app_upgrade/FlutterAppUpgradePlugin.kt +++ b/flutter_app_upgrade/android/src/main/kotlin/com/flutter/flutter_app_upgrade/FlutterAppUpgradePlugin.kt @@ -59,12 +59,16 @@ public class FlutterAppUpgradePlugin : FlutterPlugin, MethodCallHandler, Activit if (call.method == "getAppInfo") { getAppInfo(mContext, result) } else if (call.method == "getApkDownloadPath") { - result.success(mContext.getExternalFilesDir("").absolutePath) + result.success(mContext.getExternalFilesDir("")?.absolutePath) } else if (call.method == "install") { - //安装app - val path = call.argument("path") - path?.also { - startInstall(mContext, it) + if (BuildConfig.googlePlay) { + result.error("error", "googlePlay=true, The app installation function is disabled.", null) + } else { + // 安装app + val path = call.argument("path") + path?.also { + startInstall(mContext, it) + } } } else if (call.method == "getInstallMarket") { var packageList = getInstallMarket(call.argument>("packages")) @@ -124,7 +128,7 @@ public class FlutterAppUpgradePlugin : FlutterPlugin, MethodCallHandler, Activit if (nameEmpty || classEmpty) { goToMarket.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) } else { - goToMarket.setClassName(marketPackageName, marketClassName) + goToMarket.setClassName(marketPackageName!!, marketClassName!!) } context.startActivity(goToMarket) } catch (e: ActivityNotFoundException) { @@ -155,13 +159,8 @@ public class FlutterAppUpgradePlugin : FlutterPlugin, MethodCallHandler, Activit fun isPackageExist(context: Context, packageName: String?): Boolean { val manager = context.packageManager val intent = Intent().setPackage(packageName) - val infos = manager.queryIntentActivities(intent, - PackageManager.GET_INTENT_FILTERS) - return if (infos == null || infos.size < 1) { - false - } else { - true - } + val infos = manager.queryIntentActivities(intent, 0) + return infos.size > 0 } /** diff --git a/flutter_app_upgrade/example/android/app/build.gradle b/flutter_app_upgrade/example/android/app/build.gradle index 433d295..62a20ac 100644 --- a/flutter_app_upgrade/example/android/app/build.gradle +++ b/flutter_app_upgrade/example/android/app/build.gradle @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 28 + compileSdkVersion 31 sourceSets { main.java.srcDirs += 'src/main/kotlin' @@ -40,7 +40,7 @@ android { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.flutter.flutter_app_upgrade_example" minSdkVersion 16 - targetSdkVersion 28 + targetSdkVersion 31 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/flutter_app_upgrade/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/flutter_app_upgrade/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java index 8d57f25..f6e8a22 100644 --- a/flutter_app_upgrade/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java +++ b/flutter_app_upgrade/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java @@ -2,6 +2,7 @@ import androidx.annotation.Keep; import androidx.annotation.NonNull; +import io.flutter.Log; import io.flutter.embedding.engine.FlutterEngine; @@ -12,7 +13,12 @@ */ @Keep public final class GeneratedPluginRegistrant { + private static final String TAG = "GeneratedPluginRegistrant"; public static void registerWith(@NonNull FlutterEngine flutterEngine) { - flutterEngine.getPlugins().add(new com.flutter.flutter_app_upgrade.FlutterAppUpgradePlugin()); + try { + flutterEngine.getPlugins().add(new com.flutter.flutter_app_upgrade.FlutterAppUpgradePlugin()); + } catch(Exception e) { + Log.e(TAG, "Error registering plugin flutter_app_upgrade, com.flutter.flutter_app_upgrade.FlutterAppUpgradePlugin", e); + } } } diff --git a/flutter_app_upgrade/example/android/gradle.properties b/flutter_app_upgrade/example/android/gradle.properties index 38c8d45..623ed9d 100644 --- a/flutter_app_upgrade/example/android/gradle.properties +++ b/flutter_app_upgrade/example/android/gradle.properties @@ -2,3 +2,4 @@ org.gradle.jvmargs=-Xmx1536M android.enableR8=true android.useAndroidX=true android.enableJetifier=true +flutter_app_upgrade_googlePlayDefaultValue=false \ No newline at end of file diff --git a/flutter_app_upgrade/example/android/local.properties b/flutter_app_upgrade/example/android/local.properties deleted file mode 100644 index 397825c..0000000 --- a/flutter_app_upgrade/example/android/local.properties +++ /dev/null @@ -1,3 +0,0 @@ -sdk.dir=/Users/mengqingdong/Library/Android/sdk -flutter.sdk=/Users/mengqingdong/flutter -flutter.buildMode=debug \ No newline at end of file diff --git a/flutter_app_upgrade/example/lib/main.dart b/flutter_app_upgrade/example/lib/main.dart index 4f19a10..3f25484 100644 --- a/flutter_app_upgrade/example/lib/main.dart +++ b/flutter_app_upgrade/example/lib/main.dart @@ -1,5 +1,6 @@ -import 'package:flutter/material.dart'; import 'dart:async'; + +import 'package:flutter/material.dart'; import 'package:flutter_app_upgrade/flutter_app_upgrade.dart'; void main() => runApp(MyApp()); @@ -44,7 +45,7 @@ class Home extends StatefulWidget { } class _HomeState extends State { - AppInfo _appInfo; + AppInfo? _appInfo; List _appMarketList = []; String _installMarkets = ''; @@ -79,6 +80,27 @@ class _HomeState extends State { ); } + ///自定义界面 + _checkAppUpgrade2() { + AppUpgrade.appUpgrade(context, _checkAppInfo(), + iosAppId: 'id88888888', + downloadProgress: (count, total) { + print('count:$count,total:$total'); + }, + downloadStatusChange: (DownloadStatus status, {dynamic error}) { + print('status:$status,error:$error'); + }, + dialogBuilder: (onOk) => MaterialButton( + onPressed: onOk, + padding: EdgeInsets.symmetric(horizontal: 40, vertical: 2), + color: Colors.blueAccent, + child: Text("升级", + style: const TextStyle(color: Colors.white, fontSize: 16)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20)), + )); + } + Future _checkAppInfo() async { //这里一般访问网络接口,将返回的数据解析成如下格式 return Future.delayed(Duration(seconds: 1), () { @@ -121,4 +143,4 @@ class _HomeState extends State { ], ); } -} \ No newline at end of file +} diff --git a/flutter_app_upgrade/example/pubspec.yaml b/flutter_app_upgrade/example/pubspec.yaml index f2e8cb0..56a8ab0 100644 --- a/flutter_app_upgrade/example/pubspec.yaml +++ b/flutter_app_upgrade/example/pubspec.yaml @@ -3,7 +3,7 @@ description: Demonstrates how to use the flutter_app_upgrade plugin. publish_to: 'none' environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: flutter: diff --git a/flutter_app_upgrade/example/test/widget_test.dart b/flutter_app_upgrade/example/test/widget_test.dart index b84635a..a3af28e 100644 --- a/flutter_app_upgrade/example/test/widget_test.dart +++ b/flutter_app_upgrade/example/test/widget_test.dart @@ -18,8 +18,8 @@ void main() { // Verify that platform version is retrieved. expect( find.byWidgetPredicate( - (Widget widget) => widget is Text && - widget.data.startsWith('Running on:'), + (Widget widget) => + widget is Text && widget.data!.startsWith('Running on:'), ), findsOneWidget, ); diff --git a/flutter_app_upgrade/lib/src/app_market.dart b/flutter_app_upgrade/lib/src/app_market.dart index 87b7925..6e60aa4 100644 --- a/flutter_app_upgrade/lib/src/app_market.dart +++ b/flutter_app_upgrade/lib/src/app_market.dart @@ -27,8 +27,8 @@ class AppMarket { return marketList; } - static AppMarketInfo getBuildInMarket(String packageName) { - AppMarketInfo _info; + static AppMarketInfo? getBuildInMarket(String packageName) { + AppMarketInfo? _info; buildInMarketList.forEach((f) { if (f.packageName == packageName) { _info = f; @@ -50,6 +50,7 @@ class AppMarket { zte, qiHoo, tencent, + coolApk, pp, wanDouJia ]; @@ -104,6 +105,15 @@ class AppMarket { "com.tencent.android.qqdownloader", "com.tencent.pangu.link.LinkProxyActivity"); + /// + /// 酷安 + /// + static final coolApk = AppMarketInfo( + 'cookApk', + 'com.coolapk.market', + 'com.coolapk.market.view.main.MainActivity', + ); + /// /// pp助手 /// diff --git a/flutter_app_upgrade/lib/src/app_upgrade.dart b/flutter_app_upgrade/lib/src/app_upgrade.dart index b7855ed..fddb493 100644 --- a/flutter_app_upgrade/lib/src/app_upgrade.dart +++ b/flutter_app_upgrade/lib/src/app_upgrade.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_app_upgrade/flutter_app_upgrade.dart'; +import 'custom_app_upgrade.dart'; import 'download_status.dart'; import 'simple_app_upgrade.dart'; @@ -47,27 +48,28 @@ class AppUpgrade { /// /// `downloadStatusChange`:下载状态变化回调 /// - static appUpgrade( + static void appUpgrade( BuildContext context, - Future future, { - TextStyle titleStyle, - TextStyle contentStyle, - String cancelText, - TextStyle cancelTextStyle, - String okText, - TextStyle okTextStyle, - List okBackgroundColors, - Color progressBarColor, + Future future, { + TextStyle? titleStyle, + TextStyle? contentStyle, + String? cancelText, + TextStyle? cancelTextStyle, + String? okText, + TextStyle? okTextStyle, + List? okBackgroundColors, + Color? progressBarColor, double borderRadius = 20.0, - String iosAppId, - AppMarketInfo appMarketInfo, - VoidCallback onCancel, - VoidCallback onOk, - DownloadProgressCallback downloadProgress, - DownloadStatusChangeCallback downloadStatusChange, + required String iosAppId, + AppMarketInfo? appMarketInfo, + VoidCallback? onCancel, + VoidCallback? onOk, + DownloadProgressCallback? downloadProgress, + DownloadStatusChangeCallback? downloadStatusChange, + Widget Function(VoidCallback onOk)? dialogBuilder, }) { - future.then((AppUpgradeInfo appUpgradeInfo) { - if (appUpgradeInfo != null && appUpgradeInfo.title != null) { + future.then((AppUpgradeInfo? appUpgradeInfo) { + if (appUpgradeInfo != null) { _showUpgradeDialog( context, appUpgradeInfo.title, appUpgradeInfo.contents, apkDownloadUrl: appUpgradeInfo.apkDownloadUrl, @@ -86,7 +88,9 @@ class AppUpgrade { onCancel: onCancel, onOk: onOk, downloadProgress: downloadProgress, - downloadStatusChange: downloadStatusChange); + downloadStatusChange: downloadStatusChange, + //自定义升级界面 + dialogBuilder: dialogBuilder); } }).catchError((onError) { print('$onError'); @@ -96,27 +100,28 @@ class AppUpgrade { /// /// 展示app升级提示框 /// - static _showUpgradeDialog( + static void _showUpgradeDialog( BuildContext context, String title, List contents, { - String apkDownloadUrl, + String? apkDownloadUrl, bool force = false, - TextStyle titleStyle, - TextStyle contentStyle, - String cancelText, - TextStyle cancelTextStyle, - String okText, - TextStyle okTextStyle, - List okBackgroundColors, - Color progressBarColor, + TextStyle? titleStyle, + TextStyle? contentStyle, + String? cancelText, + TextStyle? cancelTextStyle, + String? okText, + TextStyle? okTextStyle, + List? okBackgroundColors, + Color? progressBarColor, double borderRadius = 20.0, - String iosAppId, - AppMarketInfo appMarketInfo, - VoidCallback onCancel, - VoidCallback onOk, - DownloadProgressCallback downloadProgress, - DownloadStatusChangeCallback downloadStatusChange, + required String iosAppId, + AppMarketInfo? appMarketInfo, + VoidCallback? onCancel, + VoidCallback? onOk, + DownloadProgressCallback? downloadProgress, + DownloadStatusChangeCallback? downloadStatusChange, + Widget Function(VoidCallback onOk)? dialogBuilder, }) { showDialog( context: context, @@ -126,42 +131,52 @@ class AppUpgrade { onWillPop: () async { return false; }, - child: Dialog( - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.all(Radius.circular(borderRadius))), - child: SimpleAppUpgradeWidget( - title: title, - titleStyle: titleStyle, - contents: contents, - contentStyle: contentStyle, - cancelText: cancelText, - cancelTextStyle: cancelTextStyle, - okText: okText, - okTextStyle: okTextStyle, - okBackgroundColors: okBackgroundColors ?? - [ - Theme.of(context).primaryColor, - Theme.of(context).primaryColor - ], - progressBarColor: progressBarColor, - borderRadius: borderRadius, - downloadUrl: apkDownloadUrl, - force: force, - iosAppId: iosAppId, - appMarketInfo: appMarketInfo, - onCancel: onCancel, - onOk: onOk, - downloadProgress: downloadProgress, - downloadStatusChange: downloadStatusChange - )), + child: dialogBuilder != null + ? Dialog( + insetPadding: + EdgeInsets.symmetric(horizontal: 0.0, vertical: 0.0), + child: CustomAppUpgradeWidget( + iosAppId: iosAppId, dialogBuilder: dialogBuilder), + backgroundColor: Colors.transparent, + ) + : Dialog( + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.all(Radius.circular(borderRadius))), + child: SimpleAppUpgradeWidget( + title: title, + titleStyle: titleStyle, + contents: contents, + contentStyle: contentStyle, + cancelText: cancelText, + cancelTextStyle: cancelTextStyle, + okText: okText, + okTextStyle: okTextStyle, + okBackgroundColors: okBackgroundColors ?? + [ + Theme.of(context).primaryColor, + Theme.of(context).primaryColor + ], + progressBarColor: progressBarColor, + borderRadius: borderRadius, + downloadUrl: apkDownloadUrl, + force: force, + iosAppId: iosAppId, + appMarketInfo: appMarketInfo, + onCancel: onCancel, + onOk: onOk, + downloadProgress: downloadProgress, + downloadStatusChange: downloadStatusChange)), ); }); } } class AppInfo { - AppInfo({this.versionName, this.versionCode, this.packageName}); + AppInfo( + {required this.versionName, + required this.versionCode, + required this.packageName}); String versionName; String versionCode; @@ -170,8 +185,8 @@ class AppInfo { class AppUpgradeInfo { AppUpgradeInfo( - {@required this.title, - @required this.contents, + {required this.title, + required this.contents, this.apkDownloadUrl, this.force = false}); @@ -188,7 +203,7 @@ class AppUpgradeInfo { /// /// apk下载url /// - final String apkDownloadUrl; + final String? apkDownloadUrl; /// /// 是否强制升级 diff --git a/flutter_app_upgrade/lib/src/custom_app_upgrade.dart b/flutter_app_upgrade/lib/src/custom_app_upgrade.dart new file mode 100644 index 0000000..bbf7f00 --- /dev/null +++ b/flutter_app_upgrade/lib/src/custom_app_upgrade.dart @@ -0,0 +1,130 @@ +import 'dart:io'; + +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_app_upgrade/flutter_app_upgrade.dart'; +import 'package:flutter_app_upgrade/src/download_status.dart'; + +/// +/// des:自定义UI +/// +class CustomAppUpgradeWidget extends StatefulWidget { + const CustomAppUpgradeWidget( + {this.downloadUrl, + this.force = false, + required this.iosAppId, + this.appMarketInfo, + this.onOk, + required this.dialogBuilder, + this.downloadProgress, + this.downloadStatusChange}); + + /// + /// app安装包下载url,没有下载跳转到应用宝等渠道更新 + /// + final String? downloadUrl; + + /// + /// 是否强制升级,设置true没有取消按钮 + /// + final bool force; + + /// + /// ios app id,用于跳转app store + /// + final String iosAppId; + + final Widget Function(VoidCallback onOk) dialogBuilder; + + /// + /// 指定跳转的应用市场, + /// 如果不指定将会弹出提示框,让用户选择哪一个应用市场。 + /// + final AppMarketInfo? appMarketInfo; + + final VoidCallback? onOk; + final DownloadProgressCallback? downloadProgress; + final DownloadStatusChangeCallback? downloadStatusChange; + + @override + State createState() => _CustomAppUpgradeWidget(); +} + +class _CustomAppUpgradeWidget extends State { + static final String _downloadApkName = 'temp.apk'; + + /// + /// 下载进度 + /// + double _downloadProgress = 0.0; + + DownloadStatus _downloadStatus = DownloadStatus.none; + + @override + Widget build(BuildContext context) { + return widget.dialogBuilder(_onOk); + } + + void _onOk() { + _clickOk(); + } + + /// + /// 点击确定按钮 + /// + _clickOk() async { + widget.onOk?.call(); + if (Platform.isIOS) { + //ios 需要跳转到app store更新,原生实现 + FlutterUpgrade.toAppStore(widget.iosAppId); + return; + } + if (widget.downloadUrl == null || widget.downloadUrl!.isEmpty) { + //没有下载地址,跳转到第三方渠道更新,原生实现 + FlutterUpgrade.toMarket(appMarketInfo: widget.appMarketInfo); + } + String path = await FlutterUpgrade.apkDownloadPath; + _downloadApk(widget.downloadUrl!, '$path/$_downloadApkName'); + } + + /// + /// 下载apk包 + /// + _downloadApk(String url, String path) async { + if (_downloadStatus == DownloadStatus.start || + _downloadStatus == DownloadStatus.downloading || + _downloadStatus == DownloadStatus.done) { + print('当前下载状态:$_downloadStatus,不能重复下载。'); + return; + } + + _updateDownloadStatus(DownloadStatus.start); + try { + var dio = Dio(); + await dio.download(url, path, onReceiveProgress: (int count, int total) { + if (total == -1) { + _downloadProgress = 0.01; + } else { + widget.downloadProgress?.call(count, total); + _downloadProgress = count / total.toDouble(); + } + setState(() {}); + if (_downloadProgress == 1) { + //下载完成,跳转到程序安装界面 + _updateDownloadStatus(DownloadStatus.done); + Navigator.pop(context); + FlutterUpgrade.installAppForAndroid(path); + } + }); + } catch (e) { + print('$e'); + _downloadProgress = 0; + _updateDownloadStatus(DownloadStatus.error, error: e); + } + } + + _updateDownloadStatus(DownloadStatus downloadStatus, {dynamic error}) { + _downloadStatus = downloadStatus; + widget.downloadStatusChange?.call(_downloadStatus, error: error); + } +} diff --git a/flutter_app_upgrade/lib/src/flutter_upgrade.dart b/flutter_app_upgrade/lib/src/flutter_upgrade.dart index 512876e..3856e39 100644 --- a/flutter_app_upgrade/lib/src/flutter_upgrade.dart +++ b/flutter_app_upgrade/lib/src/flutter_upgrade.dart @@ -4,7 +4,8 @@ import 'package:flutter/services.dart'; import 'package:flutter_app_upgrade/flutter_app_upgrade.dart'; class FlutterUpgrade { - static const MethodChannel _channel = const MethodChannel('flutter_app_upgrade'); + static const MethodChannel _channel = + const MethodChannel('flutter_app_upgrade'); /// /// 获取app信息 @@ -43,7 +44,8 @@ class FlutterUpgrade { /// /// 获取android手机上安装的应用商店 /// - static getInstallMarket({List marketPackageNames}) async { + static Future> getInstallMarket( + {List? marketPackageNames}) async { List packageNameList = AppMarket.buildInPackageNameList; if (marketPackageNames != null && marketPackageNames.length > 0) { packageNameList.addAll(marketPackageNames); @@ -59,7 +61,7 @@ class FlutterUpgrade { /// /// 跳转到应用商店 /// - static toMarket({AppMarketInfo appMarketInfo}) async { + static toMarket({AppMarketInfo? appMarketInfo}) async { var map = { 'marketPackageName': appMarketInfo != null ? appMarketInfo.packageName : '', diff --git a/flutter_app_upgrade/lib/src/liquid_progress_indicator.dart b/flutter_app_upgrade/lib/src/liquid_progress_indicator.dart index a74139d..ff9b884 100644 --- a/flutter_app_upgrade/lib/src/liquid_progress_indicator.dart +++ b/flutter_app_upgrade/lib/src/liquid_progress_indicator.dart @@ -12,19 +12,19 @@ class LiquidLinearProgressIndicator extends ProgressIndicator { final double borderRadius; ///The widget to show in the center of the progress indicator. - final Widget center; + final Widget? center; ///The direction the liquid travels. final Axis direction; LiquidLinearProgressIndicator({ - Key key, + Key? key, double value = 0.5, - Color backgroundColor, - Animation valueColor, - this.borderWidth, - this.borderColor, - this.borderRadius, + Color? backgroundColor, + Animation? valueColor, + required this.borderWidth, + required this.borderColor, + required this.borderRadius, this.center, this.direction = Axis.horizontal, }) : super( @@ -32,12 +32,7 @@ class LiquidLinearProgressIndicator extends ProgressIndicator { value: value, backgroundColor: backgroundColor, valueColor: valueColor, - ) { - if (borderWidth != null && borderColor == null || - borderColor != null && borderWidth == null) { - throw ArgumentError("borderWidth and borderColor should both be set."); - } - } + ); Color _getBackgroundColor(BuildContext context) => backgroundColor ?? Color(0x0000BFFF); //Theme.of(context).backgroundColor; @@ -70,7 +65,7 @@ class _LiquidLinearProgressIndicatorState child: Stack( children: [ Wave( - value: widget.value, + value: widget.value ?? 0.5, color: widget._getValueColor(context), direction: widget.direction, ), @@ -86,7 +81,7 @@ class _LinearPainter extends CustomPainter { final Color color; final double radius; - _LinearPainter({@required this.color, @required this.radius}); + _LinearPainter({required this.color, required this.radius}); @override void paint(Canvas canvas, Size size) { @@ -94,7 +89,7 @@ class _LinearPainter extends CustomPainter { canvas.drawRRect( RRect.fromRectAndRadius( Rect.fromLTWH(0, 0, size.width, size.height), - Radius.circular(radius ?? 0), + Radius.circular(radius), ), paint); } @@ -109,27 +104,23 @@ class _LinearBorderPainter extends CustomPainter { final double radius; _LinearBorderPainter({ - @required this.color, - @required this.width, - @required this.radius, + required this.color, + required this.width, + required this.radius, }); @override void paint(Canvas canvas, Size size) { - if (color == null || width == null) { - return; - } - final paint = Paint() ..color = color ..style = PaintingStyle.stroke ..strokeWidth = width; - final alteredRadius = radius ?? 0; + final alteredRadius = radius; canvas.drawRRect( RRect.fromRectAndRadius( Rect.fromLTWH( width / 2, width / 2, size.width - width, size.height - width), - Radius.circular(alteredRadius - width ?? 0), + Radius.circular(alteredRadius - width), ), paint); } @@ -144,7 +135,7 @@ class _LinearBorderPainter extends CustomPainter { class _LinearClipper extends CustomClipper { final double radius; - _LinearClipper({@required this.radius}); + _LinearClipper({required this.radius}); @override Path getClip(Size size) { @@ -152,7 +143,7 @@ class _LinearClipper extends CustomClipper { ..addRRect( RRect.fromRectAndRadius( Rect.fromLTWH(0, 0, size.width, size.height), - Radius.circular(radius ?? 0), + Radius.circular(radius), ), ); return path; diff --git a/flutter_app_upgrade/lib/src/simple_app_upgrade.dart b/flutter_app_upgrade/lib/src/simple_app_upgrade.dart index d02ab25..ae3f71a 100644 --- a/flutter_app_upgrade/lib/src/simple_app_upgrade.dart +++ b/flutter_app_upgrade/lib/src/simple_app_upgrade.dart @@ -12,9 +12,9 @@ import 'liquid_progress_indicator.dart'; /// class SimpleAppUpgradeWidget extends StatefulWidget { const SimpleAppUpgradeWidget( - {@required this.title, + {required this.title, this.titleStyle, - @required this.contents, + required this.contents, this.contentStyle, this.cancelText, this.cancelTextStyle, @@ -26,7 +26,7 @@ class SimpleAppUpgradeWidget extends StatefulWidget { this.borderRadius = 10, this.downloadUrl, this.force = false, - this.iosAppId, + required this.iosAppId, this.appMarketInfo, this.onCancel, this.onOk, @@ -41,7 +41,7 @@ class SimpleAppUpgradeWidget extends StatefulWidget { /// /// 标题样式 /// - final TextStyle titleStyle; + final TextStyle? titleStyle; /// /// 升级提示内容 @@ -51,47 +51,47 @@ class SimpleAppUpgradeWidget extends StatefulWidget { /// /// 提示内容样式 /// - final TextStyle contentStyle; + final TextStyle? contentStyle; /// /// 下载进度条 /// - final Widget progressBar; + final Widget? progressBar; /// /// 进度条颜色 /// - final Color progressBarColor; + final Color? progressBarColor; /// /// 确认控件 /// - final String okText; + final String? okText; /// /// 确认控件样式 /// - final TextStyle okTextStyle; + final TextStyle? okTextStyle; /// /// 确认控件背景颜色,2种颜色左到右线性渐变 /// - final List okBackgroundColors; + final List? okBackgroundColors; /// /// 取消控件 /// - final String cancelText; + final String? cancelText; /// /// 取消控件样式 /// - final TextStyle cancelTextStyle; + final TextStyle? cancelTextStyle; /// /// app安装包下载url,没有下载跳转到应用宝等渠道更新 /// - final String downloadUrl; + final String? downloadUrl; /// /// 圆角半径 @@ -112,12 +112,12 @@ class SimpleAppUpgradeWidget extends StatefulWidget { /// 指定跳转的应用市场, /// 如果不指定将会弹出提示框,让用户选择哪一个应用市场。 /// - final AppMarketInfo appMarketInfo; + final AppMarketInfo? appMarketInfo; - final VoidCallback onCancel; - final VoidCallback onOk; - final DownloadProgressCallback downloadProgress; - final DownloadStatusChangeCallback downloadStatusChange; + final VoidCallback? onCancel; + final VoidCallback? onOk; + final DownloadProgressCallback? downloadProgress; + final DownloadStatusChangeCallback? downloadStatusChange; @override State createState() => _SimpleAppUpgradeWidget(); @@ -154,16 +154,18 @@ class _SimpleAppUpgradeWidget extends State { /// Widget _buildInfoWidget(BuildContext context) { return Container( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - //标题 - _buildTitle(), - //更新信息 - _buildAppInfo(), - //操作按钮 - _buildAction() - ], + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + //标题 + _buildTitle(), + //更新信息 + _buildAppInfo(), + //操作按钮 + _buildAction() + ], + ), ), ); } @@ -174,7 +176,7 @@ class _SimpleAppUpgradeWidget extends State { _buildTitle() { return Padding( padding: EdgeInsets.only(top: 20, bottom: 30), - child: Text(widget.title ?? '', + child: Text(widget.title, style: widget.titleStyle ?? TextStyle(fontSize: 22))); } @@ -184,7 +186,7 @@ class _SimpleAppUpgradeWidget extends State { _buildAppInfo() { return Container( padding: EdgeInsets.only(left: 15, right: 15, bottom: 30), - height: 200, + constraints: BoxConstraints(maxHeight: 150, minHeight: 120), child: ListView( children: widget.contents.map((f) { return Text( @@ -257,8 +259,7 @@ class _SimpleAppUpgradeWidget extends State { bottomLeft: Radius.circular(widget.borderRadius)); } var _okBackgroundColors = widget.okBackgroundColors; - if (widget.okBackgroundColors == null || - widget.okBackgroundColors.length != 2) { + if (_okBackgroundColors == null || _okBackgroundColors.length != 2) { _okBackgroundColors = [ Theme.of(context).primaryColor, Theme.of(context).primaryColor @@ -297,6 +298,8 @@ class _SimpleAppUpgradeWidget extends State { valueColor: AlwaysStoppedAnimation(widget.progressBarColor ?? Theme.of(context).primaryColor.withOpacity(0.4)), borderRadius: widget.borderRadius, + borderColor: Colors.transparent, + borderWidth: 0, ); } @@ -310,13 +313,13 @@ class _SimpleAppUpgradeWidget extends State { FlutterUpgrade.toAppStore(widget.iosAppId); return; } - if (widget.downloadUrl == null || widget.downloadUrl.isEmpty) { + if (widget.downloadUrl == null || widget.downloadUrl!.isEmpty) { //没有下载地址,跳转到第三方渠道更新,原生实现 FlutterUpgrade.toMarket(appMarketInfo: widget.appMarketInfo); return; } String path = await FlutterUpgrade.apkDownloadPath; - _downloadApk(widget.downloadUrl, '$path/$_downloadApkName'); + _downloadApk(widget.downloadUrl!, '$path/$_downloadApkName'); } /// @@ -351,7 +354,7 @@ class _SimpleAppUpgradeWidget extends State { } catch (e) { print('$e'); _downloadProgress = 0; - _updateDownloadStatus(DownloadStatus.error,error: e); + _updateDownloadStatus(DownloadStatus.error, error: e); } } diff --git a/flutter_app_upgrade/lib/src/wave.dart b/flutter_app_upgrade/lib/src/wave.dart index f8927e5..5d5b7c6 100644 --- a/flutter_app_upgrade/lib/src/wave.dart +++ b/flutter_app_upgrade/lib/src/wave.dart @@ -8,10 +8,10 @@ class Wave extends StatefulWidget { final Axis direction; const Wave({ - Key key, - @required this.value, - @required this.color, - @required this.direction, + Key? key, + required this.value, + required this.color, + required this.direction, }) : super(key: key); @override @@ -19,7 +19,7 @@ class Wave extends StatefulWidget { } class _WaveState extends State with SingleTickerProviderStateMixin { - AnimationController _animationController; + late AnimationController _animationController; @override void initState() { @@ -65,9 +65,9 @@ class _WaveClipper extends CustomClipper { final Axis direction; _WaveClipper({ - @required this.animationValue, - @required this.value, - @required this.direction, + required this.animationValue, + required this.value, + required this.direction, }); @override @@ -94,7 +94,7 @@ class _WaveClipper extends CustomClipper { for (int i = -2; i <= size.height.toInt() + 2; i++) { final waveHeight = (size.width / 20); final dx = math.sin((animationValue * 360 - i) % 360 * (math.pi / 180)) * - waveHeight + + waveHeight + (size.width * value); waveList.add(Offset(dx, i.toDouble())); } @@ -106,7 +106,7 @@ class _WaveClipper extends CustomClipper { for (int i = -2; i <= size.width.toInt() + 2; i++) { final waveHeight = (size.height / 20); final dy = math.sin((animationValue * 360 - i) % 360 * (math.pi / 180)) * - waveHeight + + waveHeight + (size.height - (size.height * value)); waveList.add(Offset(i.toDouble(), dy)); } @@ -116,4 +116,4 @@ class _WaveClipper extends CustomClipper { @override bool shouldReclip(_WaveClipper oldClipper) => animationValue != oldClipper.animationValue; -} \ No newline at end of file +} diff --git a/flutter_app_upgrade/pubspec.yaml b/flutter_app_upgrade/pubspec.yaml index f66d504..9800138 100644 --- a/flutter_app_upgrade/pubspec.yaml +++ b/flutter_app_upgrade/pubspec.yaml @@ -4,13 +4,13 @@ version: 1.1.0 homepage: http://laomengit.com/plugin/upgrade.html environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: flutter: sdk: flutter - dio: ^3.0.9 + dio: ^4.0.0 dev_dependencies: flutter_test: