短信助手

dyb
王亚玲 2 years ago
parent 862f4f351c
commit a034c5c9f5

@ -39,14 +39,24 @@ android {
targetSdkVersion 32
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
// multiDexEnabled true
// manifestPlaceholders = [
// JPUSH_PKGNAME : applicationId,
// JPUSH_APPKEY : "", // NOTE: JPush Appkey.
// JPUSH_CHANNEL : "developer-default", //.
// ]
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
// debug {
// signingConfig signingConfigs.release
// }
}
}

@ -1,7 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.project_telephony">
<application
android:label="project_telephony"
android:label="短信帮手"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity

@ -1,26 +1,26 @@
buildscript {
ext.kotlin_version = '1.6.10'
repositories {
// maven { url 'https://maven.aliyun.com/repository/google' }
// maven { url 'https://maven.aliyun.com/repository/jcenter' }
// maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
google()
mavenCentral()
// google()
// mavenCentral()
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter'}
maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
// maven { url 'https://maven.aliyun.com/repository/google' }
// maven { url 'https://maven.aliyun.com/repository/jcenter' }
// maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
google()
mavenCentral()
// google()
// mavenCentral()
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/jcenter'}
maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

@ -0,0 +1,92 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:project_telephony/utils/headers.dart';
const ktextPrimary = Color(0xff333333);
const ktextSubColor = Color(0xff666666);
const ktextThirdColor = Color(0xff999999);
const kForeGroundColor = Color(0xFFFFFFFF);
const kPrimaryColor = Color(0xFF027AFF);
const kDarkPrimaryColor = Color(0xFFFF8200);
const kDangerColor = Color(0xFFFF3B30);
const kDarkSubColor = Color(0xFF979797);
const kBalckSubColor = Color(0xFF000000);
const bgColor = Color(0xFFF8F9FB);
class BaseStyle {
///
static final double fontSize14 = 14.sp;
static final double fontSize16 = 16.sp;
static final double fontSize18 = 18.sp;
static final double fontSize20 = 20.sp;
static final double fontSize22 = 22.sp;
static final double fontSize24 = 24.sp;
static final double fontSize26 = 26.sp;
static final double fontSize28 = 28.sp;
static final double fontSize30 = 30.sp;
static final double fontSize32 = 32.sp;
static final double fontSize34 = 34.sp;
static final double fontSize36 = 36.sp;
static final double fontSize38 = 38.sp;
static final double fontSize40 = 40.sp;
static final double fontSize48 = 48.sp;
static final double fontSize52 = 52.sp;
///
static const Color color111111 = Color(0xff111111);
static const Color color333333 = Color(0xff333333);
static const Color color666666 = Color(0xff666666);
static const Color color999999 = Color(0xff999999);
static const Color colorcccccc = Color(0xffcccccc);
static const Color colordddddd = Color(0xffdddddd);
static const Color colorfafafa = Color(0xfffafafa);
static const Color colorf3f3f3 = Color(0xfff3f3f3);
static const Color colorf6f6f6 = Color(0xfff6f6f6);
static const Color colorf9f9f9 = Color(0xfff9f9f9);
static const Color color474747 = Color(0xff474747);
static const Color colord8d8d8 = Color(0xffd8d8d8);
static const Color coloreeeeee = Color(0xffeeeeee);
static const Color colorff8500 = Color(0xffff8500);
static const Color colorffd000 = Color(0xffffd000);
static const Color color575757 = Color(0xff575757);
static const Color color4a4b51 = Color(0xff4a4b51);
static const Color colorababab = Color(0xffababab);
static const Color colorffc40c = Color(0xffffc40c);
static const Color color979797 = Color(0xff979797);
}

@ -0,0 +1,11 @@
import 'package:flutter/material.dart';
extension ColorExt on Color {
///
Color get complementary {
var r = ~red;
var g = ~green;
var b = ~blue;
return Color.fromARGB(alpha, r, g, b);
}
}

@ -0,0 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
extension NumExt on num {
Widget get wb => SizedBox(width: w);
Widget get hb => SizedBox(height: w);
}

@ -0,0 +1,71 @@
import 'package:lpinyin/lpinyin.dart';
// import '../constants/api/api.dart';
extension ImageOnString on String? {
// String get imageWithHost => '${API.imageHost}/$this';
// String sizeImage(int width, [int? height]) {
// var parts = <String>[];
// parts.add('w=$width');
// if (height != null) parts.add('h=$height');
// return '$imageWithHost@${parts.join('&')}';
// }
String get toSnake {
RegExp exp = RegExp(r'(?<=[a-z])[A-Z]');
if (this == null) {
return '';
}
return this!
.replaceAllMapped(exp, (Match m) => ('_${m.group(0)!}'))
.toLowerCase();
}
String get pinyin => PinyinHelper.getPinyinE(this ?? '');
String get tag => pinyin.substring(0, 1).toUpperCase();
int get minPrice {
if (this == null || this!.isEmpty) {
return 0;
} else if (this!.contains('不限')) {
return 0;
} else if (this!.contains('以下')) {
return 0;
} else if (this!.contains('以上')) {
return int.parse(this!.substring(0, this!.length - 3)) * 10000;
} else {
{
var list = this!.split('-');
return int.parse(list[0]) * 10000;
}
}
}
int get maxPrice {
if (this == null || this!.isEmpty) {
return 0;
} else if (this!.contains('不限')) {
return 0;
} else if (this!.contains('以下')) {
return int.parse(this!.substring(0, this!.length - 3)) * 10000;
}
if (this!.contains('以上')) {
return 0;
} else {
var list = this!.split('-');
return int.parse(list[1].substring(0, list[1].length - 1)) * 10000;
}
}
int get maxMile {
if (this == null || this!.isEmpty) {
return 0;
} else {
return int.parse(this!.substring(0, this!.length - 4));
}
}
}

@ -0,0 +1,41 @@
import 'package:flutter/material.dart';
import 'num_ext.dart';
extension WidgetListExt on List<Widget> {
List<Widget> sepWidget({Widget? separate}) {
if (isEmpty) return [];
return List.generate(length * 2 - 1, (index) {
if (index.isEven) {
return this[index ~/ 2];
} else {
return separate ?? 10.wb;
}
});
}
}
extension OddListExt<T> on List<T> {
List<T> oddList() {
List<T> _newList = [];
for (var element in this) {
if (indexOf(element).isEven) {
_newList.add(element);
}
}
return _newList;
}
}
extension EvenListExt<T> on List<T> {
List<T> evenList() {
List<T> _newList = [];
forEach((element) {
if (indexOf(element).isOdd) {
_newList.add(element);
}
});
return _newList;
}
}

@ -0,0 +1,147 @@
/// GENERATED CODE - DO NOT MODIFY BY HAND
/// *****************************************************
/// FlutterGen
/// *****************************************************
// coverage:ignore-file
// ignore_for_file: type=lint
// ignore_for_file: directives_ordering,unnecessary_import
import 'package:flutter/widgets.dart';
class $AssetsIconsGen {
const $AssetsIconsGen();
/// File path: assets/icons/home_ selected.png
AssetGenImage get homeSelected =>
const AssetGenImage('assets/icons/home_ selected.png');
/// File path: assets/icons/home_noSelected.png
AssetGenImage get homeNoSelected =>
const AssetGenImage('assets/icons/home_noSelected.png');
/// File path: assets/icons/my_noselected.png
AssetGenImage get myNoselected =>
const AssetGenImage('assets/icons/my_noselected.png');
/// File path: assets/icons/my_selected.png
AssetGenImage get mySelected =>
const AssetGenImage('assets/icons/my_selected.png');
/// File path: assets/icons/permissions.png
AssetGenImage get permissions =>
const AssetGenImage('assets/icons/permissions.png');
/// File path: assets/icons/privacy.png
AssetGenImage get privacy => const AssetGenImage('assets/icons/privacy.png');
/// File path: assets/icons/switch1.png
AssetGenImage get switch1 => const AssetGenImage('assets/icons/switch1.png');
/// File path: assets/icons/weixin.png
AssetGenImage get weixin => const AssetGenImage('assets/icons/weixin.png');
/// File path: assets/icons/zhifubao.png
AssetGenImage get zhifubao =>
const AssetGenImage('assets/icons/zhifubao.png');
}
class $AssetsImagesGen {
const $AssetsImagesGen();
/// File path: assets/images/answer.png
AssetGenImage get answer => const AssetGenImage('assets/images/answer.png');
/// File path: assets/images/banner.png
AssetGenImage get banner => const AssetGenImage('assets/images/banner.png');
/// File path: assets/images/bg.png
AssetGenImage get bg => const AssetGenImage('assets/images/bg.png');
/// File path: assets/images/home_bg.png
AssetGenImage get homeBg => const AssetGenImage('assets/images/home_bg.png');
/// File path: assets/images/portrait.png
AssetGenImage get portrait =>
const AssetGenImage('assets/images/portrait.png');
/// File path: assets/images/refused.png
AssetGenImage get refused => const AssetGenImage('assets/images/refused.png');
/// File path: assets/images/vipbanner.png
AssetGenImage get vipbanner =>
const AssetGenImage('assets/images/vipbanner.png');
/// File path: assets/images/vipbg.png
AssetGenImage get vipbg => const AssetGenImage('assets/images/vipbg.png');
}
class Assets {
Assets._();
static const $AssetsIconsGen icons = $AssetsIconsGen();
static const $AssetsImagesGen images = $AssetsImagesGen();
}
class AssetGenImage {
const AssetGenImage(this._assetName);
final String _assetName;
Image image({
Key? key,
AssetBundle? bundle,
ImageFrameBuilder? frameBuilder,
ImageErrorWidgetBuilder? errorBuilder,
String? semanticLabel,
bool excludeFromSemantics = false,
double? scale,
double? width,
double? height,
Color? color,
Animation<double>? opacity,
BlendMode? colorBlendMode,
BoxFit? fit,
AlignmentGeometry alignment = Alignment.center,
ImageRepeat repeat = ImageRepeat.noRepeat,
Rect? centerSlice,
bool matchTextDirection = false,
bool gaplessPlayback = false,
bool isAntiAlias = false,
String? package,
FilterQuality filterQuality = FilterQuality.low,
int? cacheWidth,
int? cacheHeight,
}) {
return Image.asset(
_assetName,
key: key,
bundle: bundle,
frameBuilder: frameBuilder,
errorBuilder: errorBuilder,
semanticLabel: semanticLabel,
excludeFromSemantics: excludeFromSemantics,
scale: scale,
width: width,
height: height,
color: color,
opacity: opacity,
colorBlendMode: colorBlendMode,
fit: fit,
alignment: alignment,
repeat: repeat,
centerSlice: centerSlice,
matchTextDirection: matchTextDirection,
gaplessPlayback: gaplessPlayback,
isAntiAlias: isAntiAlias,
package: package,
filterQuality: filterQuality,
cacheWidth: cacheWidth,
cacheHeight: cacheHeight,
);
}
String get path => _assetName;
String get keyName => _assetName;
}

@ -1,7 +1,12 @@
import 'dart:async';
import 'package:call_log/call_log.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_background_service/flutter_background_service.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get_navigation/src/root/get_material_app.dart';
import 'package:project_telephony/ui/login/login_page.dart';
import 'package:telephony/telephony.dart';
onBackgroundMessage(SmsMessage message) {
@ -12,6 +17,9 @@ Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await initializeService();
runApp(const MyApp());
SystemUiOverlayStyle systemUiOverlayStyle = const SystemUiOverlayStyle(
statusBarColor: Colors.transparent, //
statusBarIconBrightness: Brightness.dark); //
}
Future<void> initializeService() async {
@ -32,25 +40,29 @@ Future<void> initializeService() async {
void onIosBackground() {
WidgetsFlutterBinding.ensureInitialized();
print('FLUTTER BACKGROUND FETCH');
// print('FLUTTER BACKGROUND FETCH');
}
void onStart() {
int flag = 0;
String? phoneNum,callState;
String? phoneNum, callState;
WidgetsFlutterBinding.ensureInitialized();
Timer.periodic(const Duration(seconds: 1), (timer) async {
CallState state = await Telephony.instance.callState;
callState=state.name;
print(callState!+"$flag");
callState = state.name;
// print(callState!+"$flag");
if (callState == "IDLE") {
if (flag != 0) {
flag = 0;
final Iterable<CallLogEntry> result = await CallLog.query();
phoneNum = await result.first.number;
print(phoneNum);
Phone.telephony.sendSms(to: phoneNum!, message: "hello",isMultipart:true,);
phoneNum = result.first.number;
// print(phoneNum);
Phone.telephony.sendSms(
to: phoneNum!,
message: "hello",
isMultipart: true,
);
}
} else if (callState == "RINGING") {
flag++;
@ -60,7 +72,7 @@ void onStart() {
});
}
class Phone{
class Phone {
static Telephony telephony = Telephony.instance;
}
@ -78,6 +90,13 @@ class _MyAppState extends State<MyApp> {
void initState() {
super.initState();
final service = FlutterBackgroundService();
// JPush jPush=JPush();
// jPush.setup(
// appKey: "",
// channel: "theChannel",
// production: false,
// debug: true
// );
service.start();
}
@ -104,23 +123,31 @@ class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
onPressed: () async {
Phone.telephony.sendSms(to: "10086", message: "1");
return MediaQuery(
data: MediaQueryData.fromWindow(WidgetsBinding.instance!.window),
child: ScreenUtilInit(
designSize: const Size(750, 1334),
builder: (context, child) {
return const AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
statusBarColor: Colors.transparent, //
statusBarIconBrightness: Brightness.dark),
child: GetMaterialApp(
// get.testmode=true,
debugShowCheckedModeBanner: false,
home: LoginPage(),
// supportedLocales: [Locale('zh')],
// locale: Locale('zh'),
// builder: ( context,child){
// ScreenUtil.setContext(context);
// return MediaQuery(
// //
// data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
// // child: BotToastInit().call(context, child),
// );
// },
));
},
child: const Text('sms')),
],
),
),
);
));
}
}

@ -0,0 +1,44 @@
import 'package:flutter/material.dart';
import 'package:project_telephony/utils/headers.dart';
import '../../base/base_style.dart';
import '../widget/plone_back_button.dart';
import '../widget/plone_bottom.dart';
class ContentDetailsPage extends StatefulWidget {
const ContentDetailsPage({Key? key}) : super(key: key);
@override
_ContentDetailsPageState createState() => _ContentDetailsPageState();
}
class _ContentDetailsPageState extends State<ContentDetailsPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'选择短信内容',
style: Theme.of(context).textTheme.headline6,
),
leading: const CloudBackButton(isSpecial: true),
backgroundColor: kForeGroundColor
),
body: _getBox(),
);
}
_getBox(){
return Column(children: [
Container(
width: 622.w,
height: 960.w,
decoration: BoxDecoration(color: BaseStyle.colorcccccc,borderRadius: BorderRadius.circular(16)),
margin: EdgeInsets.only(left: 32.w,right: 32.w,top: 32.w,bottom: 298.w),
child: const Text('请输入短信内容'),),
PloneBottom(onTap: (){
},text: "保存",)
]);
}
}

@ -0,0 +1,86 @@
import 'package:flutter/material.dart';
import 'package:project_telephony/base/base_style.dart';
import 'package:project_telephony/ui/home/content_details_page.dart';
import 'package:project_telephony/ui/widget/plone_back_button.dart';
import 'package:project_telephony/utils/headers.dart';
class ContentPage extends StatefulWidget {
const ContentPage({Key? key}) : super(key: key);
@override
_ContentPageState createState() => _ContentPageState();
}
class _ContentPageState extends State<ContentPage> {
List<String> textList = ['欢迎你的来电', '祝您生活愉快', '感谢您的来电我们会尽快处理的'];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'选择短信内容',
style: Theme.of(context).textTheme.headline6,
),
leading: const CloudBackButton(isSpecial: true),
backgroundColor: kForeGroundColor,
),
body: Column(children: [
Expanded(
child: _getList(),
),
_getBox2("自定义短信内容"),
32.hb
]),
);
}
_getList() {
return ListView.builder(
itemBuilder: (context, index) {
return _getBox(textList[index], index == 0);
},
itemCount: textList.length,
);
}
_getBox(String content, bool pd) {
return Container(
width: 686.w,
height: 122.w,
margin: EdgeInsets.only(top: 32.w, left: 32.w, right: 32.w),
padding: EdgeInsets.symmetric(horizontal: 32.w, vertical: 30.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: pd ? Colors.blue : Colors.white,
),
child: Text(content,
style: TextStyle(
fontSize: BaseStyle.fontSize28,
color: pd ? const Color(0xFFF9F9F9) : BaseStyle.color333333)),
);
}
_getBox2(
String content,
) {
return GestureDetector(
onTap: () {
Get.to(() => const ContentDetailsPage());
},
child: Container(
width: 686.w,
height: 122.w,
margin: EdgeInsets.only(top: 32.w, left: 32.w, right: 32.w),
padding: EdgeInsets.symmetric(horizontal: 32.w, vertical: 30.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: Colors.white,
),
child: Text(
content,
style: TextStyle(
fontSize: BaseStyle.fontSize28, color: const Color(0xFF000000)),
)),
);
}
}

@ -0,0 +1,112 @@
import 'package:flutter/material.dart';
import 'package:project_telephony/ui/home/content_page.dart';
import 'package:project_telephony/utils/headers.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Column(
children: [
Container(
//margin:EdgeInsets.symmetric(horizontal: 32.w,vertical: 16.w),
child: Image.asset(
Assets.images.homeBg.path,
)),
12.hb,
_getBody(),
],
),
);
}
_getBody() {
return Container(
padding: EdgeInsets.symmetric(horizontal: 32.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"短信助手",
style: TextStyle(
fontSize: 64.sp,
color: Colors.black,
fontWeight: FontWeight.bold),
),
32.hb,
Text(
"希望能成为您的短信小助手",
style: TextStyle(fontSize: 32.sp, color: const Color(0xFF999999)),
),
50.hb,
_getContainer("接听后", "编辑接听后发送的短信内容", Assets.images.answer.path,
const Color(0xFF74BCFF), const Color(0xFF1890FF)),
30.hb,
_getContainer("拒接/未接后", "编辑拒接/未接后发送的短信内容", Assets.images.refused.path,
const Color(0xFF72E4C8), const Color(0xFF13CA9D))
],
),
);
}
_getContainer(String title, String text, String image, Color cl1, Color cl2) {
return GestureDetector(
onTap: () {
print(title);
if (title == "接听后") {
Get.to(() => const ContentPage());
// print("接听");
} else {
print("未接听");
}
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16.w),
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [cl1, cl2])),
child: Row(
children: [
Container(
width: 532.w,
padding: EdgeInsets.symmetric(horizontal: 32.w, vertical: 16.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title,
style: TextStyle(
fontSize: 36.sp,
color: const Color(0xFFFFFFFF),
fontWeight: FontWeight.bold)),
24.hb,
Text(
text,
style: TextStyle(
fontSize: 28.sp,
color: const Color(0xFFFFFFFF).withOpacity(0.6)),
)
],
),
),
45.wb,
Image.asset(
image,
width: 108.w,
height: 66.h,
)
],
),
),
);
}
}

@ -0,0 +1,369 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:project_telephony/utils/headers.dart';
import '../../base/base_style.dart';
import '../tab_navigator.dart';
import '../widget/image_scaffold.dart';
import '../widget/plone_bottom.dart';
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
// String _operator="";
// String _phone="";
// bool _chooseAgreement = false;
// bool _getCodeEnable = true;
// late Timer _timer;
//
// ///
// String _countDownStr = "发送验证码";
//
// ///
// int _countDownNum = 59;
///
late final TextEditingController _phoneController =
TextEditingController(text: "");
late final TextEditingController _smsCodeController =
TextEditingController(text: "");
// // late FocusNode _smsCodeFocusNode=FocusNode (canRequestFocus: );
// bool _cantSelected = false;
@override
void initState() {
super.initState();
// _operator = '中国移动认证';
// _phone = '12345678909';
}
@override
Widget build(BuildContext context) {
return CloudScaffold(
systemStyle: const SystemUiOverlayStyle(
statusBarIconBrightness: Brightness.dark,
),
path: Assets.images.bg.path,
appbar: Row(
children: [
Padding(
padding: EdgeInsets.only(top: 88.w, left: 8.w),
child: const Icon(
CupertinoIcons.chevron_back,
color: Colors.black,
),
),
Padding(
padding: EdgeInsets.only(left: 239.w, top: 88.w),
child: Text(
"登录/注册",
style: TextStyle(
fontSize: BaseStyle.fontSize34,
color: BaseStyle.color333333,
fontWeight: FontWeight.bold),
))
],
),
extendBody: true,
body: Container(
padding: EdgeInsets.only(left: 64.w, right: 64.w, top: 138.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"短信帮手",
style: TextStyle(
fontSize: 64.sp,
fontWeight: FontWeight.bold,
color: Colors.black),
),
32.hb,
Text(
"希望能成为您的短信小助手",
style: TextStyle(fontSize: 32.sp, color: const Color(0xFF999999)),
),
80.hb,
_phoneTFWidget(),
_codeWidget(),
112.hb,
PloneBottom(
onTap: () {
Get.to(() => const TabNavigator());
},
text: "立即登录",
),
32.hb,
_getText()
],
),
),
);
}
//
_phoneTFWidget() {
return Container(
alignment: Alignment.centerLeft,
// padding: EdgeInsets.symmetric(horizontal: 72.w),
height: 40 * 2.h,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: TextField(
onChanged: (String phone) {
// setState(() {
// if (phone.length >= 11) {
// _getCodeEnable = true;
// } else {
// _getCodeEnable = false;
// }
// if (kDebugMode) {
// //print(_loginEnable);
// }
// });
},
// enabled: false,
controller: _phoneController,
// focusNode: _phoneFocusNode,
keyboardType: TextInputType.number,
style: TextStyle(
fontSize: 36.sp, color: const Color(0xFF999999)),
inputFormatters: [
LengthLimitingTextInputFormatter(11),
],
cursorColor: Colors.black,
decoration: InputDecoration(
// contentPadding: EdgeInsets.only(
// left: rSize(10), top: rSize(13)),
// prefixIcon: Container(
// // padding: EdgeInsets.only(right: 10.w),
// width: 50.w,
// alignment: Alignment.centerLeft,
// child: Text(
// "+86",
// style: TextStyle(
// fontSize: 32.sp,
// color: const Color(0xFF000000)),
// ),
// ),
prefixText: "+86",
prefixStyle: TextStyle(
color: Colors.black,
),
enabledBorder: const UnderlineInputBorder(
//
borderSide: BorderSide(
color: Color(0xffdddddd),
),
),
// focusedBorder: const UnderlineInputBorder( //
// borderSide: BorderSide(
// color: Color(0x19000000)
// ),
// ),
//border: InputBorder.none,
hintText:
"请输入手机号", // hintText: _phone.replaceFirst(RegExp(r'\d{4}'), '****', 3),
hintStyle: TextStyle(
color: const Color(0xFFCCCCCC), fontSize: 32.sp),
suffixIcon: GestureDetector(
onTap: () {},
// onTap: !_getCodeEnable
// ? () {}
// : () async {
// // await apiClient
// // .request(API.login.phoneCode, data: {
// // 'phone':
// // UserTool.userProvider.userInfo.phone,
// // });
// _beginCountDown();
// if (_cantSelected) return;
// _cantSelected = true;
// Future.delayed(const Duration(seconds: 1),
// () {
// _cantSelected = false;
// });
// },
child: Container(
width: 180.w,
alignment: Alignment.centerRight,
color: Colors.transparent,
child: const Text("获取验证码"
// _countDownStr,
// style: TextStyle(
// color: _getCodeEnable
// ? kPrimaryColor
// : BaseStyle.colorcccccc),
),
),
)),
),
),
],
),
),
//_bottomLineWidget(),
],
),
);
}
//
_codeWidget() {
return Container(
alignment: Alignment.centerLeft,
//margin: EdgeInsets.symmetric(horizontal: 20.w),
// padding: EdgeInsets.symmetric(horizontal: 72.w),
height: 40 * 2.h,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: TextField(
onChanged: (String phone) {
setState(() {});
},
controller: _smsCodeController,
// focusNode: _smsCodeFocusNode,
keyboardType: TextInputType.number,
style: TextStyle(
fontSize: 36.sp, color: BaseStyle.color999999),
inputFormatters: [
LengthLimitingTextInputFormatter(4),
],
cursorColor: Colors.black,
decoration: InputDecoration(
// prefixIcon: Container(
// width: 10.w,
// alignment: Alignment.centerLeft,
// child: Text(
// "验证码",
// style: TextStyle(
// fontSize: 32.sp,
// color: const Color(0xFF000000)),
// ),
// ),
prefixText: "验证码",
prefixStyle: const TextStyle(
color: Colors.black,
),
enabledBorder: const UnderlineInputBorder(
//
borderSide: BorderSide(
color: BaseStyle.color999999,
),
),
hintText: "请输入验证码",
hintStyle: TextStyle(
color: BaseStyle.colorcccccc, fontSize: 36.sp),
)),
),
],
),
),
//_bottomLineWidget(),
],
),
);
}
// //
// _beginCountDown() {
// ///
// setState(() {
// _getCodeEnable = false;
// _countDownStr = "重新获取($_countDownNum)";
// });
// _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
// if (!mounted) {
// return;
// }
// setState(() {
// if (_countDownNum == 0) {
// _countDownNum = 59;
// _countDownStr = "获取验证码";
// _getCodeEnable = true;
// _timer.cancel();
// return;
// }
// _countDownStr = "重新获取(${_countDownNum--})";
// });
// });
// }
//
_recognizer(context, int type) {
final TapGestureRecognizer recognizer = TapGestureRecognizer();
recognizer.onTap = () {
if (kDebugMode) {
print("点击协议了");
}
///
};
return recognizer;
}
_getText() {
return GestureDetector(
onTap: () {
// _chooseAgreement = !_chooseAgreement;
setState(() {});
},
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 50.w,
height: 50.w,
padding: EdgeInsets.only(top: 6.w, right: 5.w),
child: const Icon(CupertinoIcons.circle,
size: 18, color: Color(0xFFdddddd))),
// !_chooseAgreement
// ? const Icon(CupertinoIcons.circle,
// size: 18, color: Color(0xFFdddddd))
// : const Icon(CupertinoIcons.checkmark_circle,
// size: 18, color: Colors.red)),
RichText(
text: TextSpan(
text: "我已阅读并同意",
style: TextStyle(
color: BaseStyle.colorcccccc, fontSize: 12 * 2.sp),
children: [
TextSpan(
text: '《用户服务协议》',
style: TextStyle(color: kPrimaryColor, fontSize: 12 * 2.sp),
recognizer: _recognizer(context, 2)),
TextSpan(
text: "",
style: TextStyle(
color: BaseStyle.colorcccccc, fontSize: 12 * 2.sp),
),
TextSpan(
text: '《隐私协议》',
style: TextStyle(color: kPrimaryColor, fontSize: 12 * 2.sp),
recognizer: _recognizer(context, 1)),
])),
],
),
);
}
}

@ -0,0 +1,97 @@
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/material.dart';
import 'package:project_telephony/ui/user/user_page.dart';
import 'package:project_telephony/utils/headers.dart';
import 'home/home_page.dart';
class TabNavigator extends StatefulWidget {
final int? index;
const TabNavigator({Key? key, this.index}) : super(key: key);
@override
_TabNavigatorState createState() => _TabNavigatorState();
}
class _TabNavigatorState extends State<TabNavigator>
with SingleTickerProviderStateMixin {
TabController? _tabController;
int _pageIndex = 0;
DateTime? _lastPressed;
//
List<Widget> _pages = <Widget>[];
@override
void initState() {
super.initState();
//
Future.delayed(const Duration(milliseconds: 0), () async {
// Hive.initFLutter;
// await HiveStore.init()
});
_pages = [const HomePage(), const UserPage()];
_tabController = TabController(
length: _pages.length, vsync: this, initialIndex: widget.index ?? 0);
}
//
_buildBottomBar(String title, String unSelected, String selected) {
return BottomNavigationBarItem(
icon: Image.asset(
unSelected,
height: 44.w,
width: 44.w,
),
activeIcon: Image.asset(
selected,
height: 44.w,
width: 44.w,
),
label: title,
);
}
@override
Widget build(BuildContext context) {
//
List<BottomNavigationBarItem> _bottomNav = <BottomNavigationBarItem>[
_buildBottomBar("首页", Assets.icons.homeNoSelected.path,
Assets.icons.homeSelected.path),
_buildBottomBar(
"我的", Assets.icons.myNoselected.path, Assets.icons.mySelected.path)
];
return Scaffold(
body: WillPopScope(
onWillPop: () async {
if (_lastPressed == null ||
DateTime.now().difference(_lastPressed!) >
const Duration(seconds: 1)) {
//1
_lastPressed = DateTime.now();
BotToast.showText(text: '再点击一次返回退出');
return false;
}
// APP
return true;
},
child: TabBarView(
children: _pages,
controller: _tabController,
physics: const NeverScrollableScrollPhysics(),
),
),
bottomNavigationBar: BottomNavigationBar(
items: _bottomNav,
backgroundColor: Colors.white,
currentIndex: _pageIndex,
selectedFontSize: 20.sp,
unselectedFontSize: 20.sp,
onTap: (index) {
_tabController!.animateTo(index, curve: Curves.easeInOutCubic);
setState(() => _pageIndex = index);
},
),
);
}
}

@ -0,0 +1,305 @@
import 'package:flutter/material.dart';
import 'package:project_telephony/base/base_style.dart';
import 'package:project_telephony/ui/widget/check_radio.dart';
// import 'package:project_telephony/ui/widget/check_radio.dart';
import 'package:project_telephony/ui/widget/plone_back_button.dart';
import 'package:project_telephony/ui/widget/plone_bottom.dart';
import 'package:project_telephony/ui/widget/putup_widget.dart';
import 'package:project_telephony/utils/headers.dart';
class MembersPage extends StatelessWidget {
MembersPage({Key? key}) : super(key: key);
ChooseItems? _chooseItem;
List<dynamic>? data;
final List<ChooseItems> _piceList = [
ChooseItems(
month: 12,
pice: 10,
),
ChooseItems(
month: 1,
pice: 1,
),
];
int _selectIndex = 0;
List payWay = [
{
'payName': '微信支付',
'payUrl': Assets.icons.weixin.path,
},
{'payName': '支付宝支付', 'payUrl': Assets.icons.zhifubao.path}
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
Align(
child: SizedBox(
width: 750.w,
height: 1624.w,
),
),
Positioned(
child: Image.asset(
Assets.images.vipbg.path,
)),
Positioned(top: 256.w, left: 32.w, child: _getBanner()),
Positioned(
top: 480.w,
child: Container(
height: 1208.w,
width: 750.w,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20))),
child: Column(children: [
_getRecharge(),
_getSpay(payWay),
PloneBottom(
border: true,
onTap: () {},
textColor: const Color(0xFF333333),
text: "立即开通",
color1: const Color(0xFFFFF6D8),
color2: const Color(0xFFFFEAB0),
)
]),
)),
Positioned(
top: 68.w,
child: Row(
children: [
const CloudBackButton(
isSpecial: true,
),
154.wb,
Text('会员中心', style: Theme.of(context).textTheme.headline6),
],
)),
],
));
}
// _get() {
// return Stack(
// children: [
// Align(
// child: SizedBox(
// width: 750.w,
// height: 1410.w,
// ),
// ),
// Positioned(
// child: _getBanner(),
// ),
// Positioned(
// top: 224.w,
// child: Container(
// height: 1140.w,
// width: 750.w,
// decoration: const BoxDecoration(
// color: Colors.white,
// borderRadius: BorderRadius.only(
// topLeft: Radius.circular(20),
// topRight: Radius.circular(20))),
// child: Column(children: []),
// ))
// ],
// );
// }
//banner
_getBanner() {
return SizedBox(
// margin: EdgeInsets.symmetric(horizontal: 32.w),
child: Stack(children: [
Align(
child: SizedBox(
width: 686.w,
child: Image.asset(
Assets.images.vipbanner.path,
width: 622.w,
height: 244.w,
fit: BoxFit.fill,
),
)),
Positioned(
child: Container(
margin: EdgeInsets.symmetric(horizontal: 64.w, vertical: 16.w),
child: _getText()))
]),
);
}
//banner
_getText() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_getVip(),
18.hb,
Text(
"解锁全部功能",
style: TextStyle(
color: Colors.white,
fontSize: BaseStyle.fontSize32,
fontWeight: FontWeight.bold),
),
16.hb,
Text(
"解锁全部功能",
style: TextStyle(color: Colors.white, fontSize: BaseStyle.fontSize24),
)
],
);
}
_getVip() {
return Row(
children: [
const Text(
"vip",
style: TextStyle(color: Color(0xFFFFEAB0)),
),
Container(
width: 8.w,
height: 8.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
color: const Color(0xFFFFEAB0),
),
),
const Text(
"未开通会员",
style: TextStyle(color: Color(0xFFFFEAB0)),
)
],
);
}
//
_getRecharge() {
return Container(
width: double.infinity,
decoration: const BoxDecoration(),
clipBehavior: Clip.antiAlias,
child: ListView(
shrinkWrap: true,
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: 80.w, vertical: 32.w),
child: SortWidget(
crossAxisSpacing: 24.w,
itemList: _piceList,
childAspectRatio: 288 / 216,
crossAxisCount: 2,
mainAxisSpacing: 20.w,
callback: (item, index) {
_chooseItem = item;
// setState(() {});
},
pickItem: _chooseItem,
),
),
// 762.hb,
//40.hb,
],
),
);
}
_getSpay(List item) {
return Container(
// color: Colors.red,
width: double.infinity,
height: 500.w,
margin: EdgeInsets.symmetric(horizontal: 64.w),
child: ListView.builder(
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
_selectIndex = index;
// setState(() {});
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 40.w),
color: Colors.white,
child: Row(
children: [
SizedBox(
child: Image.asset(
item[index]['payUrl'],
width: 40.w,
height: 40.h,
),
),
20.wb,
SizedBox(
width: 200.w,
child: Text(
item[index]['payName'],
style: TextStyle(
color: BaseStyle.color333333,
fontSize: BaseStyle.fontSize28),
),
),
const Spacer(),
BeeCheckRadio(
value: index,
groupValue: [_selectIndex],
),
],
)),
);
},
itemCount: item.length,
),
);
// ListView.builder(
// itemBuilder: (context, index) {
// return GestureDetector(
// onTap: () {
// _selectIndex = index;
// // setState(() {});
// },
// child: Container(
// padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 40.w),
// color: Colors.white,
// child: Row(
// children: [
// SizedBox(
// child: Image.asset(
// item[index]['payUrl'],
// width: 40.w,
// height: 40.h,
// ),
// ),
// 20.wb,
// SizedBox(
// width: 200.w,
// child: Text(
// item[index]['payName'],
// style: TextStyle(
// color: BaseStyle.color333333,
// fontSize: BaseStyle.fontSize28),
// ),
// ),
// const Spacer(),
// BeeCheckRadio(
// value: index,
// groupValue: [_selectIndex],
// ),
// ],
// )),
// );
// },
// itemCount: item.length,
// );
}
}

@ -0,0 +1,203 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:project_telephony/base/base_style.dart';
import 'package:project_telephony/ui/home/home_page.dart';
import 'package:project_telephony/ui/user/members_page.dart';
import 'package:project_telephony/ui/widget/image_scaffold.dart';
import 'package:project_telephony/ui/widget/plone_bottom.dart';
import 'package:project_telephony/utils/headers.dart';
class UserPage extends StatefulWidget {
const UserPage({Key? key}) : super(key: key);
@override
_UserPageState createState() => _UserPageState();
}
class _UserPageState extends State<UserPage> {
bool bl = true;
@override
Widget build(BuildContext context) {
return CloudScaffold(
systemStyle: const SystemUiOverlayStyle(
statusBarIconBrightness: Brightness.dark,
// systemNavigationBarColor: Colors.white,
),
path: Assets.images.bg.path,
bodyColor: Colors.white,
extendBody: true,
body: Column(children: [
_getUser(),
36.hb,
_getBanner(),
120.hb,
_getSwitch(Assets.icons.switch1.path, "功能开关", true),
_getSwitch(Assets.icons.privacy.path, "隐私政策", false),
_getSwitch(Assets.icons.permissions.path, "权限说明", false),
// const Spacer(),
PloneBottom(
border: false,
onTap: () {
Get.to(() => const HomePage());
},
textColor: const Color(0xFF1890FF),
color1: const Color(0xFFEBF5FF),
color2: const Color(0xFFEBF5FF),
text: "退出登录",
)
]),
);
}
//
_getUser() {
return Container(
margin: EdgeInsets.only(left: 32.w, right: 32.w, top: 199.w),
child: Row(
children: [
Column(
children: [
Text(
bl ? "登录/注册" : "xxxxx",
style: TextStyle(
fontSize: BaseStyle.fontSize48,
color: BaseStyle.color333333,
fontWeight: FontWeight.bold),
),
24.hb,
Text(
bl ? "登录获取更多信息" : "欢迎您登录短信帮手",
style: TextStyle(
fontSize: BaseStyle.fontSize28,
color: BaseStyle.color333333),
)
],
),
const Spacer(),
Container(
child: ClipOval(
child: Image.asset(
Assets.images.portrait.path,
height: 128.w,
width: 128.w,
fit: BoxFit.cover,
),
),
)
],
),
);
}
//banner
_getBanner() {
return SizedBox(
// margin: EdgeInsets.symmetric(horizontal: 32.w),
height: 144.w,
child: Stack(children: [
Align(
child: SizedBox(
width: 686.w,
child: Image.asset(
Assets.images.banner.path,
fit: BoxFit.fill,
),
)),
Positioned(
child: Container(
margin: EdgeInsets.symmetric(horizontal: 64.w, vertical: 16.w),
child: Row(
children: [_getText(), const Spacer(), _getBotton()],
),
))
]),
);
}
//banner botton
_getBotton() {
return GestureDetector(
onTap: () {
Get.to(() => MembersPage());
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 32.w, vertical: 16.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
gradient: const LinearGradient(
colors: [Color(0xFFFFF6D8), Color(0xFFFFEAB0)],
begin: Alignment.centerLeft,
end: Alignment.centerRight)),
child: Text(
"立即开通",
style: TextStyle(
color: const Color(0xFF001F3F), fontSize: BaseStyle.fontSize24),
)),
);
}
//banner
_getText() {
return Column(
children: [
_getVip(),
16.hb,
Text(
"解锁全部功能",
style: TextStyle(color: Colors.white, fontSize: BaseStyle.fontSize24),
)
],
);
}
_getVip() {
return Row(
children: [
const Text(
"vip",
style: TextStyle(color: Color(0xFFFFEAB0)),
),
Container(
width: 8.w,
height: 8.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
color: const Color(0xFFFFEAB0),
),
),
const Text(
"未开通会员",
style: TextStyle(color: Color(0xFFFFEAB0)),
)
],
);
}
//
_getSwitch(String url, String name, bool pd) {
bool vle = false;
return ListTile(
// onTap: (() {}),
leading: Image.asset(
url,
height: 54.w,
width: 56.w,
fit: BoxFit.fill,
),
title: Text(
name,
style: TextStyle(
color: BaseStyle.color333333,
fontSize: BaseStyle.fontSize34,
fontWeight: FontWeight.bold),
),
trailing: pd
? Switch(
value: vle,
onChanged: (value) {
vle = value;
// setState(() {});
})
: const Icon(Icons.keyboard_arrow_right));
}
}

@ -0,0 +1,68 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:project_telephony/base/base_style.dart';
import 'package:project_telephony/utils/headers.dart';
class BeeCheckRadio<T> extends StatefulWidget {
final T? value;
final List<T>? groupValue;
final Widget? indent;
final Color? backColor;
final bool? border;
const BeeCheckRadio({
Key? key,
this.value,
this.groupValue,
this.indent,
this.backColor,
this.border = true,
});
@override
_BeeCheckRadioState createState() => _BeeCheckRadioState();
}
class _BeeCheckRadioState extends State<BeeCheckRadio> {
bool get _selected {
if (widget.groupValue!.contains(widget.value)) {
return true;
} else {
return false;
}
}
@override
Widget build(BuildContext context) {
return AnimatedContainer(
height: 40.w,
width: 40.w,
decoration: widget.border!
? BoxDecoration(
color: widget.backColor ??
kPrimaryColor.withOpacity(_selected ? 1 : 0),
border: Border.all(
color: widget.backColor != null
? kForeGroundColor
: (_selected ? kPrimaryColor : const Color(0xFFcccccc)),
width: 2.w,
),
borderRadius: BorderRadius.circular(20.w),
)
: const BoxDecoration(),
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOutCubic,
alignment: Alignment.center,
child: AnimatedOpacity(
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOutCubic,
opacity: _selected ? 1 : 0,
child: widget.indent ??
Icon(
CupertinoIcons.checkmark,
color: widget.border! ? Colors.white : const Color(0xFF027AFF),
size: 28.w,
),
),
);
}
}

@ -0,0 +1,142 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:project_telephony/utils/headers.dart';
class CloudScaffold extends StatelessWidget {
///APPBar
///pathpath
final Widget? body;
final Widget? appbar;
final Color bodyColor;
final Widget? bottomNavi;
final FloatingActionButton? fab;
final bool extendBody;
final String? path;
final SystemUiOverlayStyle systemStyle;
final bool normal;
final String? title;
final List<Widget> actions;
final Color? appBarBackColor;
final PreferredSizeWidget? appBarBottom;
final Widget? endDrawer;
const CloudScaffold({
Key? key,
this.body,
this.appbar,
this.bodyColor = const Color(0xFFF9F9F9),
this.bottomNavi,
this.fab,
// this.systemStyle = SystemStyle.initial,
this.extendBody = false,
this.path,
this.endDrawer,
required this.systemStyle,
}) : normal = false,
title = '',
actions = const [],
appBarBackColor = Colors.white,
appBarBottom = null;
const CloudScaffold.white({
Key? key,
this.body,
this.bottomNavi,
this.fab,
// this.systemStyle = SystemStyle.initial,
this.extendBody = false,
this.appbar,
this.path,
this.endDrawer,
required this.systemStyle,
}) : bodyColor = Colors.white,
normal = false,
title = '',
actions = const [],
appBarBackColor = Colors.white,
appBarBottom = null;
const CloudScaffold.normal(
{Key? key,
this.body,
this.appbar,
this.bodyColor = const Color(0xFFF9F9F9),
this.bottomNavi,
this.fab,
// this.systemStyle = SystemStyle.initial,
this.extendBody = false,
this.path,
this.title,
this.appBarBackColor = Colors.white,
this.appBarBottom,
this.actions = const [],
this.endDrawer,
required this.systemStyle})
: normal = true,
assert(title != null || appbar != null);
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
return !normal
? AnnotatedRegion<SystemUiOverlayStyle>(
value: systemStyle,
child: Scaffold(
endDrawer: endDrawer,
backgroundColor: bodyColor,
extendBodyBehindAppBar: extendBody,
extendBody: extendBody,
body: Stack(
children: [
Positioned(
child: Image.asset(
path != null ? (path!) : Assets.images.homeBg.path,
width: double.infinity,
fit: BoxFit.fitWidth,
)),
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
appbar ?? const SizedBox(),
body ?? const SizedBox(),
],
)
],
),
bottomNavigationBar: bottomNavi,
floatingActionButton: fab,
),
)
: AnnotatedRegion<SystemUiOverlayStyle>(
value: systemStyle,
child: Scaffold(
endDrawer: endDrawer,
backgroundColor: bodyColor,
extendBodyBehindAppBar: extendBody,
extendBody: extendBody,
body: body,
appBar: PreferredSize(
preferredSize: Size.fromHeight(176.w),
child: title == null
? appbar!
: AppBar(
bottom: appBarBottom,
backgroundColor:
extendBody ? Colors.transparent : appBarBackColor,
// leading: const CloudBackButton(),
title: Text(
title!,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 32.sp),
),
actions: actions,
),
),
bottomNavigationBar: bottomNavi,
floatingActionButton: fab,
),
);
}
}

@ -0,0 +1,24 @@
import 'package:flutter/material.dart';
class PloneAvatarWidget extends StatelessWidget {
final List<String>? urls;
final double? width;
final double? height;
final BoxFit? fit;
const PloneAvatarWidget({Key? key, this.width,
this.height,
this.urls,
this.fit = BoxFit.cover}) : super(key: key);
// String get imagePath {
// if (urls == null) {
// return '';
// } else if (urls!.isEmpty) {
// return '';
// } else {
// return urls!.first.imageWithHost;
// }
// }
@override
Widget build(BuildContext context) {
return Container();
}
}

@ -0,0 +1,30 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:project_telephony/utils/headers.dart';
class CloudBackButton extends StatelessWidget {
final Color color;
final bool isSpecial;
const CloudBackButton({
Key? key,
this.color = const Color(0xFF111111),
this.isSpecial = false,
});
@override
Widget build(BuildContext context) {
return Navigator.canPop(context)
? Padding(
padding: isSpecial ? EdgeInsets.only(left: 8.w) : EdgeInsets.zero,
child: IconButton(
onPressed: () => Get.back(),
icon: Icon(
CupertinoIcons.chevron_back,
color: color,
),
),
)
: const SizedBox();
}
}

@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../../base/base_style.dart';
class PloneBottom extends StatefulWidget {
final String text;
final Color color1;
final Color color2;
final Color textColor;
final Function() onTap;
final bool blM; //
final bool border; //
const PloneBottom({
Key? key,
this.text = '返回首页',
this.color1 = const Color(0xFF0593FF),
this.color2 = const Color(0xFF027AFF),
this.textColor = kForeGroundColor,
this.blM = true,
this.border = false,
required this.onTap,
});
@override
State<PloneBottom> createState() => _PloneBottomState();
}
class _PloneBottomState extends State<PloneBottom> {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: widget.onTap,
child: Material(
color: Colors.transparent,
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.symmetric(vertical: 15.w),
margin: widget.blM
? EdgeInsets.symmetric(horizontal: 32.w)
: EdgeInsets.only(left: 0.w),
decoration: BoxDecoration(
border: Border.all(
color: const Color(0xFF1890FF),
width: !widget.border ? 1.w : 10.w),
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [widget.color1, widget.color2]),
borderRadius: BorderRadius.circular(8.w)),
child: Text(
widget.text,
style: TextStyle(
fontSize: BaseStyle.fontSize28, color: widget.textColor),
),
),
),
);
}
}

@ -0,0 +1,113 @@
import 'package:flutter/material.dart';
import 'package:project_telephony/base/base_style.dart';
import 'package:project_telephony/utils/headers.dart';
typedef ItemCallback = Function(ChooseItems item, int index);
class ChooseItems {
int month;
int pice;
bool isChoose;
ChooseItems({
required this.month,
required this.pice,
this.isChoose = false,
});
}
class SortWidget extends StatelessWidget {
final List<ChooseItems> itemList;
final ItemCallback callback;
final int crossAxisCount;
final double mainAxisSpacing;
final double crossAxisSpacing;
final double childAspectRatio;
final bool haveButton;
final ChooseItems? pickItem;
const SortWidget(
{Key? key,
required this.itemList,
required this.callback,
required this.crossAxisCount,
required this.mainAxisSpacing,
required this.crossAxisSpacing,
required this.childAspectRatio,
this.haveButton = false,
required this.pickItem});
@override
Widget build(BuildContext context) {
return GridView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
padding: EdgeInsets.zero,
itemCount: itemList.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
//
crossAxisCount: crossAxisCount,
//
mainAxisSpacing: mainAxisSpacing,
//
crossAxisSpacing: crossAxisSpacing,
//
childAspectRatio: childAspectRatio),
itemBuilder: (BuildContext context, int index) {
return _getItem(itemList[index], index);
});
}
_getItem(ChooseItems item, int index) {
return GestureDetector(
onTap: () {
callback(item, index);
},
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: pickItem == item
? const Color(0xFFFFFAEA)
: const Color(0xFFFFFFFF),
borderRadius: BorderRadius.circular(4.w),
border: pickItem != item
? Border.all(color: const Color(0xFFF5F5F5), width: 1.w)
: Border.all(color: const Color(0xFFFFDF66), width: 1.w)),
child: Column(
children: [
Padding(padding: EdgeInsets.only(top: 16.w)),
Text(
"${item.month}个月VIP",
style: TextStyle(
fontSize: BaseStyle.fontSize28,
color: BaseStyle.color333333,
fontWeight: FontWeight.bold),
),
Text.rich(TextSpan(children: [
TextSpan(
text: "¥",
style: TextStyle(
fontSize: BaseStyle.fontSize32,
color: pickItem == item
? const Color(0xFFFF3F3F)
: BaseStyle.color333333)),
TextSpan(
text: "${item.pice}",
style: TextStyle(
fontSize: 64.sp,
color: pickItem == item
? const Color(0xFFFF3F3F)
: BaseStyle.color333333))
])),
Text(
"${(item.pice / item.month).toStringAsFixed(2)}元/月",
style: TextStyle(
fontSize: BaseStyle.fontSize24,
color: BaseStyle.color999999,
fontWeight: FontWeight.bold),
),
],
)),
);
}
}

@ -0,0 +1,7 @@
// export 'package:cloud_car/base/base_style.dart';
export 'package:project_telephony/extensions/num_ext.dart';
export 'package:project_telephony/extensions/num_ext.dart';
export 'package:project_telephony/extensions/wigget_list_ext.dart';
export 'package:project_telephony/gen/assets.gen.dart';
export 'package:flutter_screenutil/flutter_screenutil.dart';
export 'package:get/get.dart';

@ -1,6 +1,27 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
_fe_analyzer_shared:
dependency: transitive
description:
name: _fe_analyzer_shared
url: "https://pub.dartlang.org"
source: hosted
version: "40.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
url: "https://pub.dartlang.org"
source: hosted
version: "4.1.0"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.1"
async:
dependency: transitive
description:
@ -15,6 +36,69 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
bot_toast:
dependency: "direct main"
description:
name: bot_toast
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.3"
build:
dependency: transitive
description:
name: build
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.0"
build_config:
dependency: transitive
description:
name: build_config
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
build_daemon:
dependency: transitive
description:
name: build_daemon
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
build_resolvers:
dependency: transitive
description:
name: build_resolvers
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.9"
build_runner:
dependency: "direct dev"
description:
name: build_runner
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
url: "https://pub.dartlang.org"
source: hosted
version: "7.2.3"
built_collection:
dependency: transitive
description:
name: built_collection
url: "https://pub.dartlang.org"
source: hosted
version: "5.1.1"
built_value:
dependency: transitive
description:
name: built_value
url: "https://pub.dartlang.org"
source: hosted
version: "8.4.0"
call_log:
dependency: "direct main"
description:
@ -36,6 +120,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
clock:
dependency: transitive
description:
@ -43,6 +134,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
code_builder:
dependency: transitive
description:
name: code_builder
url: "https://pub.dartlang.org"
source: hosted
version: "4.1.0"
collection:
dependency: transitive
description:
@ -50,55 +148,55 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0"
cupertino_icons:
dependency: "direct main"
color:
dependency: transitive
description:
name: cupertino_icons
name: color
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.5"
device_info_plus:
dependency: "direct main"
version: "3.0.0"
convert:
dependency: transitive
description:
name: device_info_plus
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.0"
device_info_plus_linux:
version: "3.0.2"
crypto:
dependency: transitive
description:
name: device_info_plus_linux
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
device_info_plus_macos:
dependency: transitive
version: "3.0.2"
cupertino_icons:
dependency: "direct main"
description:
name: device_info_plus_macos
name: cupertino_icons
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.3"
device_info_plus_platform_interface:
version: "1.0.5"
dart_style:
dependency: transitive
description:
name: device_info_plus_platform_interface
name: dart_style
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.0+1"
device_info_plus_web:
version: "2.2.3"
dartx:
dependency: transitive
description:
name: device_info_plus_web
name: dartx
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
device_info_plus_windows:
dependency: transitive
version: "1.1.0"
device_info_plus:
dependency: "direct main"
description:
name: device_info_plus_windows
name: device_info_plus
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
version: "0.0.1"
fake_async:
dependency: transitive
description:
@ -120,6 +218,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.2"
fixnum:
dependency: transitive
description:
name: fixnum
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
flutter:
dependency: "direct main"
description: flutter
@ -131,7 +236,42 @@ packages:
name: flutter_background_service
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.6"
version: "0.2.8+5"
flutter_background_service_android:
dependency: transitive
description:
name: flutter_background_service_android
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.2"
flutter_background_service_ios:
dependency: transitive
description:
name: flutter_background_service_ios
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.2"
flutter_background_service_platform_interface:
dependency: transitive
description:
name: flutter_background_service_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1+3"
flutter_gen_core:
dependency: transitive
description:
name: flutter_gen_core
url: "https://pub.dartlang.org"
source: hosted
version: "4.3.0"
flutter_gen_runner:
dependency: "direct dev"
description:
name: flutter_gen_runner
url: "https://pub.dartlang.org"
source: hosted
version: "4.3.0"
flutter_lints:
dependency: "direct dev"
description:
@ -139,23 +279,102 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
flutter_screenutil:
dependency: "direct main"
description:
name: flutter_screenutil
url: "https://pub.dartlang.org"
source: hosted
version: "5.5.3+2"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
frontend_server_client:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
description:
name: frontend_server_client
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
get:
dependency: "direct main"
description:
name: get
url: "https://pub.dartlang.org"
source: hosted
version: "4.6.5"
glob:
dependency: transitive
description:
name: glob
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
graphs:
dependency: transitive
description:
name: graphs
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
hive:
dependency: "direct main"
description:
name: hive
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.3"
hive_flutter:
dependency: "direct main"
description:
name: hive_flutter
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
http_multi_server:
dependency: transitive
description:
name: http_multi_server
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.1"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.1"
io:
dependency: transitive
description:
name: io
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3"
version: "0.6.4"
json_annotation:
dependency: transitive
description:
name: json_annotation
url: "https://pub.dartlang.org"
source: hosted
version: "4.6.0"
json_serializable:
dependency: "direct dev"
description:
name: json_serializable
url: "https://pub.dartlang.org"
source: hosted
version: "6.3.1"
lints:
dependency: transitive
description:
@ -163,6 +382,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
logging:
dependency: transitive
description:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
lpinyin:
dependency: "direct main"
description:
name: lpinyin
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
matcher:
dependency: transitive
description:
@ -170,6 +403,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.11"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.3"
meta:
dependency: transitive
description:
@ -177,6 +417,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
mime:
dependency: transitive
description:
name: mime
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
nested:
dependency: transitive
description:
@ -184,6 +431,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
package_config:
dependency: transitive
description:
name: package_config
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
package_info:
dependency: "direct main"
description:
name: package_info
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
path:
dependency: transitive
description:
@ -191,6 +452,62 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
path_provider:
dependency: transitive
description:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.11"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.17"
path_provider_ios:
dependency: transitive
description:
name: path_provider_ios
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.11"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.7"
path_provider_macos:
dependency: transitive
description:
name: path_provider_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.6"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.4"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.7"
petitparser:
dependency: transitive
description:
name: petitparser
url: "https://pub.dartlang.org"
source: hosted
version: "4.4.0"
platform:
dependency: transitive
description:
@ -205,6 +522,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
pool:
dependency: transitive
description:
name: pool
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.1"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.4"
provider:
dependency: "direct main"
description:
@ -212,11 +543,53 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.3"
pub_semver:
dependency: "direct dev"
description:
name: pub_semver
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
shelf:
dependency: transitive
description:
name: shelf
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.2"
shelf_web_socket:
dependency: transitive
description:
name: shelf_web_socket
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_gen:
dependency: transitive
description:
name: source_gen
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.2"
source_helper:
dependency: transitive
description:
name: source_helper
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.2"
source_span:
dependency: transitive
description:
@ -238,6 +611,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
stream_transform:
dependency: transitive
description:
name: stream_transform
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
string_scanner:
dependency: transitive
description:
@ -251,7 +631,7 @@ packages:
name: telephony
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4"
version: "0.2.0"
term_glyph:
dependency: transitive
description:
@ -265,7 +645,21 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.3"
version: "0.4.8"
time:
dependency: transitive
description:
name: time
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
timing:
dependency: transitive
description:
name: timing
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
typed_data:
dependency: transitive
description:
@ -280,6 +674,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
watcher:
dependency: transitive
description:
name: watcher
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
win32:
dependency: transitive
description:
@ -287,6 +695,27 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.5.2"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0+1"
xml:
dependency: transitive
description:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "5.3.1"
yaml:
dependency: "direct dev"
description:
name: yaml
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.1"
sdks:
dart: ">=2.15.0 <3.0.0"
flutter: ">=2.0.0"
dart: ">=2.16.1 <3.0.0"
flutter: ">=2.8.1"

@ -34,11 +34,31 @@ dependencies:
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
# 获取来电状态
telephony: any
provider: ^6.0.3
# 获取通话记录
call_log: ^4.0.0
flutter_background_service: any
# 后台设置
flutter_background_service: ^0.2.6
device_info_plus: any
# 屏幕适配
flutter_screenutil: ^5.5.3+2
# 路由相关
get: ^4.6.5
# 包的信息
package_info: ^2.0.0
# 本地化存储
hive: ^2.0.4
hive_flutter: ^1.1.0
# 弹出框
bot_toast: ^4.0.3
# 汉转音
lpinyin: ^2.0.3
# # jdk
# jverify: ^2.2.5
## pub 集成
# jpush_flutter: 2.1.4
dev_dependencies:
flutter_test:
@ -50,45 +70,20 @@ dev_dependencies:
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^1.0.0
#model自动生成
json_serializable: ^6.1.3
build_runner: ^2.0.2
yaml: ^3.1.0
pub_semver: ^2.1.0
flutter_gen_runner: ^4.1.3
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
generate: true
assets:
- assets/
- assets/icons/
- assets/images/
# - assets/data/
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages

Loading…
Cancel
Save