permission_dialog_shell.dart
4.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import 'dart:math' as math;
import 'package:flutter/material.dart';
/// 权限类弹窗的纯样式骨架
///
/// 只负责渐变背景、盾牌插画、标题、说明以及主次按钮的排版与视觉,
/// 具体的文案与按钮行为由各业务组件通过参数传入,
/// 以便「首次使用权限说明」与「权限被拒后去设置引导」保持视觉统一。
class PermissionDialogShell extends StatelessWidget {
const PermissionDialogShell({
super.key,
required this.title,
required this.description,
required this.primaryText,
required this.onPrimary,
required this.secondaryText,
required this.onSecondary,
});
/// 弹窗标题,例如:「班小二APP」需要使用相机
final String title;
/// 弹窗说明文案
final String description;
/// 主按钮文案,例如:继续
final String primaryText;
/// 主按钮点击回调
final VoidCallback onPrimary;
/// 次按钮文案,例如:暂不开启
final String secondaryText;
/// 次按钮点击回调
final VoidCallback onSecondary;
/// 盾牌插画资源
static const String shieldAsset = 'assets/images/icon/shield.png';
@override
Widget build(BuildContext context) {
return Dialog(
backgroundColor: Colors.transparent,
elevation: 0,
insetPadding: const EdgeInsets.symmetric(horizontal: 40),
child: Container(
padding: const EdgeInsets.fromLTRB(22, 0, 22, 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
gradient: const LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFFBAC8FC),
Color(0xFFFFFFFF),
],
stops: [0, 0.25],
transform: GradientRotation(20 * math.pi / 180),
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// 插画
Center(
child: Image.asset(
shieldAsset,
height: 100,
fit: BoxFit.contain,
),
),
const SizedBox(height: 16),
// 标题
Text(
title,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 17,
fontWeight: FontWeight.w600,
height: 1.4,
color: Color(0xFF1A1A1A),
),
),
const SizedBox(height: 10),
// 说明
Text(
description,
textAlign: TextAlign.left,
style: const TextStyle(
fontSize: 15,
height: 1.6,
color: Color(0xFF333333),
),
),
const SizedBox(height: 22),
// 主按钮
ClipRRect(
borderRadius: BorderRadius.circular(23),
child: Material(
color: Colors.transparent,
child: Ink(
decoration: const BoxDecoration(
color: Color(0xFF7691FA),
),
child: InkWell(
onTap: onPrimary,
child: SizedBox(
height: 46,
child: Center(
child: Text(
primaryText,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.white,
),
),
),
),
),
),
),
),
const SizedBox(height: 8),
// 次按钮
TextButton(
onPressed: onSecondary,
style: TextButton.styleFrom(
minimumSize: const Size.fromHeight(40),
foregroundColor: const Color(0xFF999999),
),
child: Text(
secondaryText,
style: const TextStyle(
fontSize: 16,
color: Color(0xFF999999),
),
),
),
],
),
),
);
}
}