Merge branch 'master' of https://git.oa00.com/austin_dai/project_telephony
# Conflicts: # lib/main.dart # pubspec.lock # pubspec.yamldyb
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 623 B |
After Width: | Height: | Size: 685 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 321 KiB |
After Width: | Height: | Size: 126 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 43 KiB |
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;
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
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';
|
||||
|
||||
typedef TextCallback = Function(String textContent);
|
||||
|
||||
class ContentDetailsPage extends StatefulWidget {
|
||||
final TextCallback ploneBack;
|
||||
final String content;
|
||||
const ContentDetailsPage(
|
||||
{Key? key, required this.content, required this.ploneBack})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
_ContentDetailsPageState createState() => _ContentDetailsPageState();
|
||||
}
|
||||
|
||||
String content = "";
|
||||
|
||||
class _ContentDetailsPageState extends State<ContentDetailsPage> {
|
||||
late TextEditingController _controller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = TextEditingController(text: widget.content);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
title: Text(
|
||||
'编辑短信内容',
|
||||
style: TextStyle(
|
||||
fontSize: BaseStyle.fontSize34,
|
||||
color: BaseStyle.color333333,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
titleSpacing: 162.w,
|
||||
leading: const CloudBackButton(isSpecial: true),
|
||||
backgroundColor: kForeGroundColor),
|
||||
backgroundColor: Colors.white,
|
||||
body: _getBox(),
|
||||
);
|
||||
}
|
||||
|
||||
_getBox() {
|
||||
return Column(children: [
|
||||
Container(
|
||||
width: 622.w,
|
||||
height: 960.w,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF9F9F9),
|
||||
borderRadius: BorderRadius.circular(16.w)),
|
||||
margin: EdgeInsets.only(top: 32.w, bottom: 298.w),
|
||||
child: Container(
|
||||
// color: kForeGroundColor,
|
||||
margin: EdgeInsets.symmetric(horizontal: 40.w, vertical: 50.w),
|
||||
child: TextField(
|
||||
maxLines: 100,
|
||||
keyboardType: TextInputType.text,
|
||||
onEditingComplete: () {
|
||||
setState(() {});
|
||||
// _refreshController.callRefresh();
|
||||
},
|
||||
onChanged: (text) {
|
||||
content = text;
|
||||
print(content);
|
||||
setState(() {});
|
||||
},
|
||||
style: TextStyle(
|
||||
color: BaseStyle.color333333,
|
||||
fontSize: BaseStyle.fontSize28,
|
||||
),
|
||||
controller: _controller,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
filled: true,
|
||||
isDense: true,
|
||||
fillColor: Colors.white,
|
||||
hintText: widget.content != "" ? "" : "请输入短信内容",
|
||||
hintStyle: TextStyle(
|
||||
color: widget.content != ""
|
||||
? const Color(0xFF333333)
|
||||
: Colors.grey.shade500,
|
||||
fontSize: 28.sp,
|
||||
fontWeight: FontWeight.bold),
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Text(widget.content,),
|
||||
),
|
||||
PloneBottom(
|
||||
border: !content.isNotEmpty,
|
||||
opacity: content.isNotEmpty ? 1 : 0.4,
|
||||
onTap: () {
|
||||
setState(() {});
|
||||
widget.ploneBack(content);
|
||||
Get.back();
|
||||
// print(content);
|
||||
},
|
||||
text: "保存",
|
||||
)
|
||||
]);
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
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/centertipsalterwidget.dart';
|
||||
|
||||
import 'package:project_telephony/ui/widget/plone_back_button.dart';
|
||||
import 'package:project_telephony/utils/headers.dart';
|
||||
|
||||
class ContentPage extends StatefulWidget {
|
||||
final bool? isAnswer; //true接听false未接听
|
||||
const ContentPage({Key? key, required this.isAnswer}) : super(key: key);
|
||||
|
||||
@override
|
||||
_ContentPageState createState() => _ContentPageState();
|
||||
}
|
||||
|
||||
class _ContentPageState extends State<ContentPage> {
|
||||
int _select = 0;
|
||||
List<String> textList = ['欢迎你的来电', '祝您生活愉快', '感谢您的来电我们会尽快处理的', '自定义短信内容'];
|
||||
List<String> textList1 = ['自定义短信内容'];
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
title: Text(
|
||||
'选择短信内容',
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
leading: const CloudBackButton(isSpecial: true),
|
||||
backgroundColor: kForeGroundColor,
|
||||
),
|
||||
backgroundColor: Colors.white,
|
||||
body: Column(children: [
|
||||
Expanded(
|
||||
child: _getList(),
|
||||
),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
_getList() {
|
||||
return ListView.builder(
|
||||
itemBuilder: (context, index) {
|
||||
return _getBox(textList[index], index == _select, index);
|
||||
},
|
||||
itemCount: textList.length,
|
||||
);
|
||||
}
|
||||
|
||||
_getBox(String content, bool pd, int index) {
|
||||
return GestureDetector(
|
||||
onTap: () async {
|
||||
_select = index;
|
||||
if (index != textList.length - 1) {
|
||||
await Get.to(() => ContentDetailsPage(
|
||||
content: content,
|
||||
ploneBack: (String textContent) {
|
||||
textList1.add(textContent);
|
||||
},
|
||||
));
|
||||
} else {
|
||||
await Get.to(() => ContentDetailsPage(
|
||||
content: "",
|
||||
ploneBack: (String textContent) {
|
||||
// print("这是数据" + textContent);
|
||||
textList.setAll(index, {textContent});
|
||||
},
|
||||
));
|
||||
setState(() {});
|
||||
}
|
||||
// print("这是数据" + textList[_s lect]);
|
||||
|
||||
// print(index);
|
||||
},
|
||||
onLongPress: () {
|
||||
setState(() {});
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return const Centertipsalterwidget(
|
||||
desText: '你确定要删除这个短信模版吗,删除之后无法还原。',
|
||||
title: '删除短信模板',
|
||||
);
|
||||
});
|
||||
},
|
||||
child: Container(
|
||||
// width: 686.w,
|
||||
height: 135.w,
|
||||
margin: EdgeInsets.only(top: 32.w, left: 64.w, right: 64.w),
|
||||
padding: EdgeInsets.only(left: 40.w, top: 50.w),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
color: pd
|
||||
? widget.isAnswer!
|
||||
? Colors.blue
|
||||
: Color(0xFF72E4C8)
|
||||
: const Color(0xFFF9F9F9),
|
||||
),
|
||||
child: Text(
|
||||
content,
|
||||
style: TextStyle(
|
||||
fontSize: BaseStyle.fontSize28,
|
||||
color: pd ? const Color(0xFFF9F9F9) : BaseStyle.color333333,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,150 @@
|
||||
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,
|
||||
extendBodyBehindAppBar: true,
|
||||
extendBody: true,
|
||||
body: SafeArea(
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
child: Image.asset(
|
||||
Assets.images.homeBg.path,
|
||||
height: 722.w,
|
||||
width: 722.w,
|
||||
)),
|
||||
_getBody(),
|
||||
],
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
_getBody() {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 64.w),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"短信帮手",
|
||||
style: TextStyle(
|
||||
fontSize: 64.sp,
|
||||
color: const Color(0xFF333333),
|
||||
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(
|
||||
isAnswer: true,
|
||||
));
|
||||
} else {
|
||||
Get.to(() => const ContentPage(
|
||||
isAnswer: false,
|
||||
));
|
||||
print("未接听");
|
||||
}
|
||||
},
|
||||
child: Stack(
|
||||
children: [
|
||||
Align(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16.w),
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
colors: [cl1, cl2])),
|
||||
width: 622.w,
|
||||
height: 192.w,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.only(
|
||||
left: 48.w,
|
||||
top: 35.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: 27.sp,
|
||||
color: const Color(0xFFFFFFFF).withOpacity(0.6)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Padding(
|
||||
// padding: EdgeInsets.only(top: 40.w),
|
||||
// child:
|
||||
|
||||
// )
|
||||
],
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
child: Image.asset(
|
||||
image,
|
||||
width: 166.w,
|
||||
height: 152.w,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
// Container(
|
||||
// decoration: BoxDecoration(
|
||||
// borderRadius: BorderRadius.circular(16.w),
|
||||
// gradient: LinearGradient(
|
||||
// end: Alignment.centerLeft,
|
||||
// begin: Alignment.centerRight,
|
||||
// colors: [cl1, cl2])),
|
||||
// child:
|
||||
|
||||
// ),
|
||||
);
|
||||
}
|
||||
}
|
@ -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,284 @@
|
||||
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/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 StatefulWidget {
|
||||
const MembersPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_MembersPageState createState() => _MembersPageState();
|
||||
}
|
||||
|
||||
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}
|
||||
];
|
||||
|
||||
class _MembersPageState extends State<MembersPage> {
|
||||
@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),
|
||||
],
|
||||
)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
//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;
|
||||
// print(_piceList[index].pice);
|
||||
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;
|
||||
// print(_selectIndex);
|
||||
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,79 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:project_telephony/base/base_style.dart';
|
||||
import 'package:project_telephony/ui/widget/plone_back_button.dart';
|
||||
import 'package:project_telephony/utils/headers.dart';
|
||||
|
||||
class PrivacyRightsPage extends StatefulWidget {
|
||||
final String name;
|
||||
const PrivacyRightsPage({Key? key, required this.name}) : super(key: key);
|
||||
|
||||
@override
|
||||
_PrivacyRightsPageState createState() => _PrivacyRightsPageState();
|
||||
}
|
||||
|
||||
class _PrivacyRightsPageState extends State<PrivacyRightsPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
title: Text(
|
||||
widget.name,
|
||||
style: TextStyle(
|
||||
fontSize: BaseStyle.fontSize34,
|
||||
color: BaseStyle.color333333,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
titleSpacing: 162.w,
|
||||
leading: const CloudBackButton(isSpecial: true),
|
||||
backgroundColor: kForeGroundColor),
|
||||
backgroundColor: Colors.white,
|
||||
body: widget.name == "隐私政策" ? null : _getRights(true),
|
||||
);
|
||||
}
|
||||
|
||||
_getRights(bool pd) {
|
||||
return GestureDetector(
|
||||
onTap: () {},
|
||||
child: Container(
|
||||
height: 144.w,
|
||||
width: 750.w,
|
||||
padding: EdgeInsets.symmetric(horizontal: 64.w, vertical: 17.w),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'获取设备来电',
|
||||
style: TextStyle(
|
||||
fontSize: 32.sp,
|
||||
color: BaseStyle.color333333,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
16.hb,
|
||||
Text('用于获取设备',
|
||||
style: TextStyle(
|
||||
fontSize: 28.sp, color: BaseStyle.color999999)),
|
||||
],
|
||||
),
|
||||
269.wb,
|
||||
Text(pd ? "未允许" : "已允许",
|
||||
style: TextStyle(
|
||||
fontSize: 24.sp,
|
||||
color: pd
|
||||
? const Color(0xFFFF4D4D)
|
||||
: BaseStyle.color999999)),
|
||||
SizedBox(
|
||||
width: 48.w,
|
||||
height: 48.w,
|
||||
child: const Icon(
|
||||
Icons.keyboard_arrow_right,
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,231 @@
|
||||
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/login/login_page.dart';
|
||||
import 'package:project_telephony/ui/user/members_page.dart';
|
||||
import 'package:project_telephony/ui/user/privacy_rights_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();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {}
|
||||
|
||||
class _UserPageState extends State<UserPage> {
|
||||
bool bl = true;
|
||||
bool vle = false;
|
||||
@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(),
|
||||
72.hb,
|
||||
_getBanner(),
|
||||
120.hb,
|
||||
_getSwitch(Assets.icons.switch1.path, "功能开关", true),
|
||||
_getSwitch(Assets.icons.privacy.path, "隐私政策", false),
|
||||
_getSwitch(Assets.icons.permissions.path, "权限说明", false),
|
||||
// const Spacer(),
|
||||
182.hb,
|
||||
PloneBottom(
|
||||
border: false,
|
||||
onTap: () {
|
||||
Get.to(() => const HomePage());
|
||||
},
|
||||
textColor: const Color(0xFF1890FF),
|
||||
color1: const Color(0xFFEBF5FF),
|
||||
color2: const Color(0xFFEBF5FF),
|
||||
text: "退出登录",
|
||||
)
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
//头像
|
||||
_getUser() {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Get.to(() => const LoginPage());
|
||||
},
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(left: 64.w, right: 64.w, top: 216.w),
|
||||
child: Row(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
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: 622.w,
|
||||
child: Image.asset(
|
||||
Assets.images.banner.path,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
)),
|
||||
Positioned(
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 112.w, vertical: 24.w),
|
||||
// margin: EdgeInsets.symmetric(horizontal: 64.w, vertical: 16.w),
|
||||
// padding: EdgeInsets.symmetric(),
|
||||
child: Row(
|
||||
children: [_getText(), const Spacer(), _getBotton()],
|
||||
),
|
||||
))
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
//banner botton
|
||||
_getBotton() {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
Get.to(() => const MembersPage());
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 32.w, vertical: 16.w),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(30.w),
|
||||
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(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
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) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
pd
|
||||
? ""
|
||||
: Get.to(() => PrivacyRightsPage(
|
||||
name: name,
|
||||
));
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 32.w),
|
||||
child: 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) {
|
||||
setState(() {
|
||||
vle = value;
|
||||
});
|
||||
})
|
||||
: const Icon(Icons.keyboard_arrow_right)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:project_telephony/utils/headers.dart';
|
||||
|
||||
class Centertipsalterwidget extends StatefulWidget {
|
||||
final String title;
|
||||
final String desText;
|
||||
const Centertipsalterwidget(
|
||||
{Key? key, required this.desText, required this.title})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
_CentertipsalterwidgetState createState() => _CentertipsalterwidgetState();
|
||||
}
|
||||
|
||||
class _CentertipsalterwidgetState extends State<Centertipsalterwidget> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CupertinoAlertDialog(
|
||||
title: Text(widget.title),
|
||||
content: Column(children: [
|
||||
SizedBox(
|
||||
height: 10.w,
|
||||
),
|
||||
Align(
|
||||
child: Text(widget.desText),
|
||||
alignment: const Alignment(0, 0),
|
||||
)
|
||||
]),
|
||||
actions: [
|
||||
CupertinoDialogAction(
|
||||
child: const Text(
|
||||
'取消',
|
||||
style: TextStyle(color: Color(0xFF999999)),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
CupertinoDialogAction(
|
||||
child: const Text('确定'),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -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,144 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:project_telephony/utils/headers.dart';
|
||||
|
||||
class CloudScaffold extends StatelessWidget {
|
||||
///沉浸式带背景的APPBar
|
||||
///path未背景图的path
|
||||
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(
|
||||
resizeToAvoidBottomInset: false,
|
||||
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(
|
||||
resizeToAvoidBottomInset: false,
|
||||
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,69 @@
|
||||
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; //是否有边框
|
||||
final double opacity;
|
||||
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,
|
||||
this.opacity = 1,
|
||||
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(
|
||||
height: 84.w,
|
||||
alignment: Alignment.center,
|
||||
padding: EdgeInsets.symmetric(vertical: 14.w),
|
||||
margin: widget.blM
|
||||
? EdgeInsets.symmetric(horizontal: 64.w)
|
||||
: EdgeInsets.only(left: 0.w),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color:
|
||||
!widget.border ? const Color(0xFF1890FF) : Colors.white,
|
||||
width: !widget.border ? 1.w : 0.w),
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.centerLeft,
|
||||
end: Alignment.centerRight,
|
||||
colors: [
|
||||
widget.color1.withOpacity(widget.opacity),
|
||||
widget.color2.withOpacity(widget.opacity)
|
||||
]),
|
||||
borderRadius: BorderRadius.circular(8.w)),
|
||||
child: Text(
|
||||
widget.text,
|
||||
style: TextStyle(
|
||||
fontSize: BaseStyle.fontSize28,
|
||||
color: widget.textColor,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
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
|
||||
// void initState() {
|
||||
// super.initState();
|
||||
|
||||
// }
|
||||
|
||||
@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';
|