mirror of
https://github.com/qinglong-app/qinglong_app.git
synced 2025-10-09 16:48:19 +08:00
添加版本更新检测功能
This commit is contained in:
BIN
assets/images/update_bg_app_top.png
Normal file
BIN
assets/images/update_bg_app_top.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.7 KiB |
BIN
assets/images/update_ic_close.png
Normal file
BIN
assets/images/update_ic_close.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
@@ -76,4 +76,6 @@ class Url {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String checkUpdateUrl = "https://raw.githubusercontent.com/qinglong-app/qinglong_app/main/version";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import 'package:qinglong_app/module/env/env_page.dart';
|
|||||||
import 'package:qinglong_app/module/others/other_page.dart';
|
import 'package:qinglong_app/module/others/other_page.dart';
|
||||||
import 'package:qinglong_app/module/task/task_page.dart';
|
import 'package:qinglong_app/module/task/task_page.dart';
|
||||||
import 'package:move_to_background/move_to_background.dart';
|
import 'package:move_to_background/move_to_background.dart';
|
||||||
|
import 'package:qinglong_app/utils/update_utils.dart';
|
||||||
|
|
||||||
class HomePage extends ConsumerStatefulWidget {
|
class HomePage extends ConsumerStatefulWidget {
|
||||||
const HomePage({Key? key}) : super(key: key);
|
const HomePage({Key? key}) : super(key: key);
|
||||||
@@ -30,6 +31,9 @@ class _HomePageState extends ConsumerState<HomePage> {
|
|||||||
initTitles();
|
initTitles();
|
||||||
_title = titles[0].title;
|
_title = titles[0].title;
|
||||||
super.initState();
|
super.initState();
|
||||||
|
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||||
|
update();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -185,6 +189,16 @@ class _HomePageState extends ConsumerState<HomePage> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update() async {
|
||||||
|
String? result = await UpdateUtils().checkUpdate();
|
||||||
|
if (result != null && result.isNotEmpty) {
|
||||||
|
UpdateDialog updateDialog = UpdateDialog(context, title: "发现新版本", updateContent: "版本号:v$result", onUpdate: () {
|
||||||
|
UpdateUtils.launchURL(result);
|
||||||
|
});
|
||||||
|
updateDialog.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class IndexBean {
|
class IndexBean {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import 'package:qinglong_app/base/userinfo_viewmodel.dart';
|
|||||||
import 'package:qinglong_app/main.dart';
|
import 'package:qinglong_app/main.dart';
|
||||||
import 'package:qinglong_app/module/login/user_bean.dart';
|
import 'package:qinglong_app/module/login/user_bean.dart';
|
||||||
import 'package:qinglong_app/utils/extension.dart';
|
import 'package:qinglong_app/utils/extension.dart';
|
||||||
|
import 'package:qinglong_app/utils/update_utils.dart';
|
||||||
import 'package:qinglong_app/utils/utils.dart';
|
import 'package:qinglong_app/utils/utils.dart';
|
||||||
import 'package:flip_card/flip_card.dart';
|
import 'package:flip_card/flip_card.dart';
|
||||||
|
|
||||||
@@ -57,6 +58,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
}
|
}
|
||||||
getIt<UserInfoViewModel>().updateToken("");
|
getIt<UserInfoViewModel>().updateToken("");
|
||||||
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||||
|
update();
|
||||||
if (useSecretLogin) {
|
if (useSecretLogin) {
|
||||||
cardKey.currentState?.toggleCard();
|
cardKey.currentState?.toggleCard();
|
||||||
}
|
}
|
||||||
@@ -483,4 +485,14 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update() async {
|
||||||
|
String? result = await UpdateUtils().checkUpdate();
|
||||||
|
if (result != null && result.isNotEmpty) {
|
||||||
|
UpdateDialog updateDialog = UpdateDialog(context, title: "发现新版本", updateContent: "版本号:v${result}", onUpdate: () {
|
||||||
|
UpdateUtils.launchURL(result);
|
||||||
|
});
|
||||||
|
updateDialog.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||||||
import 'package:qinglong_app/base/ql_app_bar.dart';
|
import 'package:qinglong_app/base/ql_app_bar.dart';
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
import 'package:qinglong_app/base/theme.dart';
|
import 'package:qinglong_app/base/theme.dart';
|
||||||
|
import 'package:qinglong_app/utils/update_utils.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
import '../../main.dart';
|
import '../../main.dart';
|
||||||
@@ -23,6 +24,20 @@ class _AboutPageState extends ConsumerState<AboutPage> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
getInfo();
|
getInfo();
|
||||||
|
|
||||||
|
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
|
||||||
|
update();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void update() async {
|
||||||
|
String? result = await UpdateUtils().checkUpdate(true);
|
||||||
|
if (result != null && result.isNotEmpty) {
|
||||||
|
UpdateDialog updateDialog = UpdateDialog(context, title: "发现新版本", updateContent: "版本号:v${result}", onUpdate: () {
|
||||||
|
UpdateUtils.launchURL(result);
|
||||||
|
});
|
||||||
|
updateDialog.show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -270,6 +270,7 @@ class TaskItemCell extends StatelessWidget {
|
|||||||
child: Text(
|
child: Text(
|
||||||
bean.name ?? "",
|
bean.name ?? "",
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
color: ref.watch(themeProvider).themeColor.titleColor(),
|
color: ref.watch(themeProvider).themeColor.titleColor(),
|
||||||
|
|||||||
395
lib/utils/update_utils.dart
Normal file
395
lib/utils/update_utils.dart
Normal file
@@ -0,0 +1,395 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
|
import 'package:qinglong_app/base/http/url.dart';
|
||||||
|
import 'package:qinglong_app/utils/extension.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
import '../main.dart';
|
||||||
|
|
||||||
|
/// @author NewTab
|
||||||
|
|
||||||
|
class UpdateUtils {
|
||||||
|
Future<String?> checkUpdate([bool remind = false]) async {
|
||||||
|
try {
|
||||||
|
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
||||||
|
|
||||||
|
String version = packageInfo.version;
|
||||||
|
String url = Url.checkUpdateUrl;
|
||||||
|
Dio dio = Dio(BaseOptions(
|
||||||
|
connectTimeout: 50000,
|
||||||
|
receiveTimeout: 50000,
|
||||||
|
sendTimeout: 50000,
|
||||||
|
));
|
||||||
|
var response = await dio.get(url);
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
if (version == response.data as String) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return response.data as String;
|
||||||
|
}
|
||||||
|
} on DioError catch (e) {
|
||||||
|
if (remind) {
|
||||||
|
"无法连接到github服务器,版本更新检测失败".toast();
|
||||||
|
}
|
||||||
|
logger.e(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void launchURL(String version) async {
|
||||||
|
try {
|
||||||
|
await launch("https://github.com/qinglong-app/qinglong_app/releases/download/v$version/app-release-v$version.apk");
|
||||||
|
} catch (e) {
|
||||||
|
logger.e(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///版本更新加提示框
|
||||||
|
class UpdateDialog {
|
||||||
|
bool _isShowing = false;
|
||||||
|
late BuildContext _context;
|
||||||
|
late UpdateWidget _widget;
|
||||||
|
|
||||||
|
UpdateDialog(BuildContext context,
|
||||||
|
{double width = 0.0,
|
||||||
|
required String title,
|
||||||
|
required String updateContent,
|
||||||
|
required VoidCallback onUpdate,
|
||||||
|
double titleTextSize = 16.0,
|
||||||
|
double contentTextSize = 14.0,
|
||||||
|
double buttonTextSize = 14.0,
|
||||||
|
double progress = -1.0,
|
||||||
|
Color progressBackgroundColor = const Color(0xFFFFCDD2),
|
||||||
|
Image? topImage,
|
||||||
|
double extraHeight = 5.0,
|
||||||
|
double radius = 4.0,
|
||||||
|
Color themeColor = Colors.red,
|
||||||
|
bool enableIgnore = false,
|
||||||
|
VoidCallback? onIgnore,
|
||||||
|
bool isForce = false,
|
||||||
|
String? updateButtonText,
|
||||||
|
String? ignoreButtonText,
|
||||||
|
VoidCallback? onClose}) {
|
||||||
|
_context = context;
|
||||||
|
_widget = UpdateWidget(
|
||||||
|
width: width,
|
||||||
|
title: title,
|
||||||
|
updateContent: updateContent,
|
||||||
|
onUpdate: onUpdate,
|
||||||
|
titleTextSize: titleTextSize,
|
||||||
|
contentTextSize: contentTextSize,
|
||||||
|
buttonTextSize: buttonTextSize,
|
||||||
|
progress: progress,
|
||||||
|
topImage: topImage,
|
||||||
|
extraHeight: extraHeight,
|
||||||
|
radius: radius,
|
||||||
|
themeColor: themeColor,
|
||||||
|
progressBackgroundColor: progressBackgroundColor,
|
||||||
|
enableIgnore: enableIgnore,
|
||||||
|
onIgnore: onIgnore,
|
||||||
|
isForce: isForce,
|
||||||
|
updateButtonText: updateButtonText ?? '更新',
|
||||||
|
ignoreButtonText: ignoreButtonText ?? '忽略此版本',
|
||||||
|
onClose: onClose ?? () => dismiss());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 显示弹窗
|
||||||
|
Future<bool> show() {
|
||||||
|
try {
|
||||||
|
if (isShowing()) {
|
||||||
|
return Future<bool>.value(false);
|
||||||
|
}
|
||||||
|
showDialog<bool>(
|
||||||
|
context: _context,
|
||||||
|
barrierDismissible: false,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return WillPopScope(onWillPop: () => Future<bool>.value(false), child: _widget);
|
||||||
|
});
|
||||||
|
_isShowing = true;
|
||||||
|
return Future<bool>.value(true);
|
||||||
|
} catch (err) {
|
||||||
|
_isShowing = false;
|
||||||
|
return Future<bool>.value(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 隐藏弹窗
|
||||||
|
Future<bool> dismiss() {
|
||||||
|
try {
|
||||||
|
if (_isShowing) {
|
||||||
|
_isShowing = false;
|
||||||
|
Navigator.pop(_context);
|
||||||
|
return Future<bool>.value(true);
|
||||||
|
} else {
|
||||||
|
return Future<bool>.value(false);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
return Future<bool>.value(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 是否显示
|
||||||
|
bool isShowing() {
|
||||||
|
return _isShowing;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 更新进度
|
||||||
|
void update(double progress) {
|
||||||
|
if (isShowing()) {
|
||||||
|
_widget.update(progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 显示版本更新提示框
|
||||||
|
static UpdateDialog showUpdate(BuildContext context,
|
||||||
|
{double width = 0.0,
|
||||||
|
required String title,
|
||||||
|
required String updateContent,
|
||||||
|
required VoidCallback onUpdate,
|
||||||
|
double titleTextSize = 16.0,
|
||||||
|
double contentTextSize = 14.0,
|
||||||
|
double buttonTextSize = 14.0,
|
||||||
|
double progress = -1.0,
|
||||||
|
Color progressBackgroundColor = const Color(0xFFFFCDD2),
|
||||||
|
Image? topImage,
|
||||||
|
double extraHeight = 5.0,
|
||||||
|
double radius = 4.0,
|
||||||
|
Color themeColor = Colors.red,
|
||||||
|
bool enableIgnore = false,
|
||||||
|
VoidCallback? onIgnore,
|
||||||
|
String? updateButtonText,
|
||||||
|
String? ignoreButtonText,
|
||||||
|
bool isForce = false}) {
|
||||||
|
final UpdateDialog dialog = UpdateDialog(context,
|
||||||
|
width: width,
|
||||||
|
title: title,
|
||||||
|
updateContent: updateContent,
|
||||||
|
onUpdate: onUpdate,
|
||||||
|
titleTextSize: titleTextSize,
|
||||||
|
contentTextSize: contentTextSize,
|
||||||
|
buttonTextSize: buttonTextSize,
|
||||||
|
progress: progress,
|
||||||
|
topImage: topImage,
|
||||||
|
extraHeight: extraHeight,
|
||||||
|
radius: radius,
|
||||||
|
themeColor: themeColor,
|
||||||
|
progressBackgroundColor: progressBackgroundColor,
|
||||||
|
enableIgnore: enableIgnore,
|
||||||
|
isForce: isForce,
|
||||||
|
updateButtonText: updateButtonText,
|
||||||
|
ignoreButtonText: ignoreButtonText,
|
||||||
|
onIgnore: onIgnore);
|
||||||
|
dialog.show();
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore: must_be_immutable
|
||||||
|
class UpdateWidget extends StatefulWidget {
|
||||||
|
/// 对话框的宽度
|
||||||
|
final double width;
|
||||||
|
|
||||||
|
/// 升级标题
|
||||||
|
final String title;
|
||||||
|
|
||||||
|
/// 更新内容
|
||||||
|
final String updateContent;
|
||||||
|
|
||||||
|
/// 标题文字的大小
|
||||||
|
final double titleTextSize;
|
||||||
|
|
||||||
|
/// 更新文字内容的大小
|
||||||
|
final double contentTextSize;
|
||||||
|
|
||||||
|
/// 按钮文字的大小
|
||||||
|
final double buttonTextSize;
|
||||||
|
|
||||||
|
/// 顶部图片
|
||||||
|
final Widget? topImage;
|
||||||
|
|
||||||
|
/// 拓展高度(适配顶部图片高度不一致的情况)
|
||||||
|
final double extraHeight;
|
||||||
|
|
||||||
|
/// 边框圆角大小
|
||||||
|
final double radius;
|
||||||
|
|
||||||
|
/// 主题颜色
|
||||||
|
final Color themeColor;
|
||||||
|
|
||||||
|
/// 更新事件
|
||||||
|
final VoidCallback onUpdate;
|
||||||
|
|
||||||
|
/// 可忽略更新
|
||||||
|
final bool enableIgnore;
|
||||||
|
|
||||||
|
/// 更新事件
|
||||||
|
final VoidCallback? onIgnore;
|
||||||
|
|
||||||
|
double progress;
|
||||||
|
|
||||||
|
/// 进度条的背景颜色
|
||||||
|
final Color progressBackgroundColor;
|
||||||
|
|
||||||
|
/// 更新事件
|
||||||
|
final VoidCallback? onClose;
|
||||||
|
|
||||||
|
/// 是否是强制更新
|
||||||
|
final bool isForce;
|
||||||
|
|
||||||
|
/// 更新按钮内容
|
||||||
|
final String updateButtonText;
|
||||||
|
|
||||||
|
/// 忽略按钮内容
|
||||||
|
final String ignoreButtonText;
|
||||||
|
|
||||||
|
UpdateWidget(
|
||||||
|
{Key? key,
|
||||||
|
this.width = 0.0,
|
||||||
|
required this.title,
|
||||||
|
required this.updateContent,
|
||||||
|
required this.onUpdate,
|
||||||
|
this.titleTextSize = 16.0,
|
||||||
|
this.contentTextSize = 14.0,
|
||||||
|
this.buttonTextSize = 14.0,
|
||||||
|
this.progress = -1.0,
|
||||||
|
this.progressBackgroundColor = const Color(0xFFFFCDD2),
|
||||||
|
this.topImage,
|
||||||
|
this.extraHeight = 5.0,
|
||||||
|
this.radius = 4.0,
|
||||||
|
this.themeColor = Colors.red,
|
||||||
|
this.enableIgnore = false,
|
||||||
|
this.onIgnore,
|
||||||
|
this.isForce = false,
|
||||||
|
this.updateButtonText = '更新',
|
||||||
|
this.ignoreButtonText = '忽略此版本',
|
||||||
|
this.onClose})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
|
final _UpdateWidgetState _state = _UpdateWidgetState();
|
||||||
|
|
||||||
|
void update(double progress) {
|
||||||
|
_state.update(progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
_UpdateWidgetState createState() => _state;
|
||||||
|
}
|
||||||
|
|
||||||
|
class _UpdateWidgetState extends State<UpdateWidget> {
|
||||||
|
void update(double progress) {
|
||||||
|
if (!mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
widget.progress = progress;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final double dialogWidth = widget.width <= 0 ? getFitWidth(context) * 0.618 : widget.width;
|
||||||
|
return Material(
|
||||||
|
type: MaterialType.transparency,
|
||||||
|
child: SizedBox(
|
||||||
|
width: dialogWidth,
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
SizedBox(
|
||||||
|
width: dialogWidth,
|
||||||
|
child: widget.topImage ?? Image.asset('assets/images/update_bg_app_top.png', fit: BoxFit.fill),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
width: dialogWidth,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
padding: const EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 8),
|
||||||
|
decoration: ShapeDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(widget.radius), bottomRight: Radius.circular(widget.radius)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.only(top: widget.extraHeight),
|
||||||
|
child: Text(widget.title, style: TextStyle(fontSize: widget.titleTextSize, color: Colors.black)),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||||
|
child: Text(widget.updateContent, style: TextStyle(fontSize: widget.contentTextSize, color: const Color(0xFF666666))),
|
||||||
|
),
|
||||||
|
Column(children: <Widget>[
|
||||||
|
FractionallySizedBox(
|
||||||
|
widthFactor: 1,
|
||||||
|
child: ElevatedButton(
|
||||||
|
style: ButtonStyle(
|
||||||
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
|
textStyle: MaterialStateProperty.all(TextStyle(fontSize: widget.buttonTextSize)),
|
||||||
|
foregroundColor: MaterialStateProperty.all(Colors.white),
|
||||||
|
shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(5))),
|
||||||
|
elevation: MaterialStateProperty.all(0),
|
||||||
|
backgroundColor: MaterialStateProperty.all(widget.themeColor),
|
||||||
|
),
|
||||||
|
child: Text(widget.updateButtonText),
|
||||||
|
onPressed: widget.onUpdate,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (widget.enableIgnore && widget.onIgnore != null)
|
||||||
|
FractionallySizedBox(
|
||||||
|
widthFactor: 1,
|
||||||
|
child: TextButton(
|
||||||
|
style: ButtonStyle(
|
||||||
|
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||||
|
textStyle: MaterialStateProperty.all(TextStyle(fontSize: widget.buttonTextSize)),
|
||||||
|
foregroundColor: MaterialStateProperty.all(const Color(0xFF666666)),
|
||||||
|
shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(5))),
|
||||||
|
),
|
||||||
|
child: Text(widget.ignoreButtonText),
|
||||||
|
onPressed: widget.onIgnore,
|
||||||
|
))
|
||||||
|
else
|
||||||
|
const SizedBox()
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
if (!widget.isForce)
|
||||||
|
Column(children: <Widget>[
|
||||||
|
const SizedBox(width: 1.5, height: 50, child: DecoratedBox(decoration: BoxDecoration(color: Colors.white))),
|
||||||
|
IconButton(
|
||||||
|
iconSize: 30,
|
||||||
|
constraints: const BoxConstraints(maxHeight: 30, maxWidth: 30),
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
icon: Image.asset(
|
||||||
|
'assets/images/update_ic_close.png',
|
||||||
|
),
|
||||||
|
onPressed: widget.onClose,
|
||||||
|
)
|
||||||
|
])
|
||||||
|
else
|
||||||
|
const SizedBox()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
double getFitWidth(BuildContext context) {
|
||||||
|
return min(getScreenHeight(context), getScreenWidth(context));
|
||||||
|
}
|
||||||
|
|
||||||
|
double getScreenHeight(BuildContext context) {
|
||||||
|
return MediaQuery.of(context).size.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getScreenWidth(BuildContext context) {
|
||||||
|
return MediaQuery.of(context).size.width;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user