[baozhangchao] 3 年之前
父節點
當前提交
c560546f3d
共有 2 個檔案被更改,包括 325 行新增190 行删除
  1. 324
    189
      lib/pages/userInfo/index.dart
  2. 1
    1
      lib/widgets/layout/BasicPage.dart

+ 324
- 189
lib/pages/userInfo/index.dart 查看文件

@@ -8,24 +8,24 @@ import 'package:worker_client/services/user.dart';
8 8
 import 'package:worker_client/widgets/MyButton/index.dart';
9 9
 import 'package:worker_client/widgets/layout/BasicPage.dart';
10 10
 
11
-class UserInfo extends BasicPage {
12
-  UserInfo({Key? key}) : super(key: key);
11
+class UserInfo extends StatefulWidget {
12
+  @override
13
+  State<StatefulWidget> createState() {
14
+    return _UserInfoState();
15
+  }
16
+}
17
+
18
+class _UserInfoState extends BoardWidget {
19
+  late TextEditingController _cName =
20
+      TextEditingController(text: store.user().nickName.toString());
21
+  late TextEditingController _cPhone =
22
+      TextEditingController(text: store.user().phone.toString());
23
+  late String name = store.user().nickName.toString();
24
+  late String phone = store.user().phone.toString();
25
+  final bool _useSystemKeyBoard = true;
13 26
 
14 27
   AppController store = AppController.t;
15
-  late String name;
16
-  late String phone;
17
-  late TextEditingController _cName;
18
-  late TextEditingController _cPhone;
19 28
 
20
-  @override
21
-  void beforeShow() {
22
-    // TODO: implement beforeShow
23
-    super.beforeShow();
24
-    _cName = TextEditingController(text: store.user().nickName.toString());
25
-    _cPhone = TextEditingController(text: store.user().phone.toString());
26
-    name = store.user().nickName.toString();
27
-    phone = store.user().phone.toString();
28
-  }
29 29
   RegExp exp = RegExp(r'^1[3456789]\d{9}$');
30 30
 
31 31
   void handleOk() {
@@ -36,7 +36,6 @@ class UserInfo extends BasicPage {
36 36
       Fluttertoast.showToast(msg: '请输入正确的手机号');
37 37
       return;
38 38
     } else {
39
-
40 39
       updateInfo(store.user().personId.toString(), {
41 40
         ...store.user().toJson(),
42 41
         'nickName': name,
@@ -49,214 +48,350 @@ class UserInfo extends BasicPage {
49 48
     }
50 49
   }
51 50
 
51
+  final TextStyle textStyle = TextStyle(
52
+      fontFamily: "hwxw",
53
+      fontSize: 20.0,
54
+      letterSpacing: 1.0,
55
+      fontWeight: FontWeight.bold,
56
+      fontStyle: FontStyle.normal,
57
+      color: Colors.black87);
58
+
59
+  final TextStyle lableStyle = TextStyle(
60
+      fontFamily: "hwxw",
61
+      fontSize: 20.0,
62
+      letterSpacing: 16.0,
63
+      fontWeight: FontWeight.bold,
64
+      fontStyle: FontStyle.normal);
65
+
66
+  final TextStyle helperStyle = TextStyle(
67
+      fontFamily: "hwxw", fontSize: 12.0, fontStyle: FontStyle.normal);
68
+
69
+  late ScrollFocusNode _userNameFocusNode;
70
+  late ScrollFocusNode _phoneFocusNode;
71
+
52 72
   @override
53
-  Widget builder(BuildContext context) {
54
-    naviTitle = '个人信息';
55
-    return Container(
56
-      padding: EdgeInsets.all(15.w),
57
-      decoration: const BoxDecoration(color: Colors.white),
58
-      child: Column(
59
-        children: [
60
-          Container(
61
-            width: 345.w,
62
-            height: 92.h,
63
-            alignment: Alignment.centerLeft,
64
-            decoration: BoxDecoration(color: Colors.white, boxShadow: [
65
-              BoxShadow(color: Color(0x1f000000), offset: Offset(0, 1.w))
66
-            ]),
67
-            child: store.user().avatar != null
68
-                ? Container(
69
-                    clipBehavior: Clip.hardEdge,
70
-                    decoration: BoxDecoration(
71
-                        borderRadius: BorderRadius.all(Radius.circular(31.w))),
72
-                    child: Image.network(
73
-                      store.user().avatar.toString(),
73
+  void initState() {
74
+    super.initState();
75
+    _userNameFocusNode =
76
+        ScrollFocusNode(_useSystemKeyBoard, 50.0); // 第二个参数是向上滚动的距离
77
+    _phoneFocusNode =
78
+        ScrollFocusNode(_useSystemKeyBoard, 120.0); // 第二个参数是向上滚动的距离
79
+  }
80
+
81
+  @override
82
+  List<Widget> initChild() {
83
+    return <Widget>[
84
+      Container(
85
+        padding: EdgeInsets.all(15.w),
86
+        decoration: const BoxDecoration(color: Colors.white),
87
+        child: Column(
88
+          children: [
89
+            Container(
90
+              width: 345.w,
91
+              height: 92.h,
92
+              alignment: Alignment.centerLeft,
93
+              decoration: BoxDecoration(color: Colors.white, boxShadow: [
94
+                BoxShadow(color: Color(0x1f000000), offset: Offset(0, 1.w))
95
+              ]),
96
+              child: store.user().avatar != null
97
+                  ? Container(
98
+                      clipBehavior: Clip.hardEdge,
99
+                      decoration: BoxDecoration(
100
+                          borderRadius:
101
+                              BorderRadius.all(Radius.circular(31.w))),
102
+                      child: Image.network(
103
+                        store.user().avatar.toString(),
104
+                        width: 62.w,
105
+                        height: 62.w,
106
+                      ),
107
+                    )
108
+                  : Image.asset(
109
+                      'images/main/defaultAvatar.png',
74 110
                       width: 62.w,
75 111
                       height: 62.w,
76 112
                     ),
77
-                  )
78
-                : Image.asset(
79
-                    'images/main/defaultAvatar.png',
80
-                    width: 62.w,
81
-                    height: 62.w,
82
-                  ),
83
-          ),
84
-          Container(
113
+            ),
114
+            Container(
115
+                width: 345.w,
116
+                alignment: Alignment.centerLeft,
117
+                margin: EdgeInsets.only(top: 40.h),
118
+                decoration: BoxDecoration(color: Colors.white, boxShadow: [
119
+                  BoxShadow(color: Color(0x1f000000), offset: Offset(0, 1.w))
120
+                ]),
121
+                child: Column(
122
+                  crossAxisAlignment: CrossAxisAlignment.start,
123
+                  children: [
124
+                    Text(
125
+                      '用户名:',
126
+                      style: TextStyle(
127
+                          color: const Color(0xFF333333),
128
+                          letterSpacing: 2,
129
+                          fontSize: 17.sp,
130
+                          fontWeight: FontWeight.bold),
131
+                    ),
132
+                    Container(
133
+                      height: 54.h,
134
+                      alignment: Alignment.centerLeft,
135
+                      child: store.user().userName != null
136
+                          ? Text(
137
+                              store.user().userName.toString(),
138
+                              style: TextStyle(
139
+                                  color: const Color(0xFF333333),
140
+                                  fontSize: 17.sp,
141
+                                  fontWeight: FontWeight.bold),
142
+                            )
143
+                          : const Text(''),
144
+                    ),
145
+                  ],
146
+                )),
147
+            Container(
85 148
               width: 345.w,
86 149
               alignment: Alignment.centerLeft,
87 150
               margin: EdgeInsets.only(top: 40.h),
88 151
               decoration: BoxDecoration(color: Colors.white, boxShadow: [
89
-                BoxShadow(color: Color(0x1f000000), offset: Offset(0, 1.w))
152
+                BoxShadow(
153
+                    color: const Color(0x1f000000), offset: Offset(0, 1.w))
90 154
               ]),
91 155
               child: Column(
92 156
                 crossAxisAlignment: CrossAxisAlignment.start,
93 157
                 children: [
94 158
                   Text(
95
-                    '用户名:',
159
+                    '名:',
96 160
                     style: TextStyle(
97 161
                         color: const Color(0xFF333333),
98
-                        letterSpacing: 2,
99 162
                         fontSize: 17.sp,
100
-                        fontWeight: FontWeight.bold),
163
+                        fontWeight: FontWeight.bold,
164
+                        letterSpacing: 2),
101 165
                   ),
102 166
                   Container(
103 167
                     height: 54.h,
104 168
                     alignment: Alignment.centerLeft,
105
-                    child: store.user().userName != null
106
-                        ? Text(
107
-                            store.user().userName.toString(),
169
+                    child: Row(
170
+                      children: [
171
+                        Expanded(
172
+                          flex: 1,
173
+                          child: TextField(
174
+                            controller: _cName,
108 175
                             style: TextStyle(
109
-                                color: const Color(0xFF333333),
110 176
                                 fontSize: 17.sp,
111
-                                fontWeight: FontWeight.bold),
112
-                          )
113
-                        : const Text(''),
114
-                  ),
115
-                ],
116
-              )),
117
-          Container(
118
-            width: 345.w,
119
-            alignment: Alignment.centerLeft,
120
-            margin: EdgeInsets.only(top: 40.h),
121
-            decoration: BoxDecoration(color: Colors.white, boxShadow: [
122
-              BoxShadow(color: const Color(0x1f000000), offset: Offset(0, 1.w))
123
-            ]),
124
-            child: Column(
125
-              crossAxisAlignment: CrossAxisAlignment.start,
126
-              children: [
127
-                Text(
128
-                  '姓名:',
129
-                  style: TextStyle(
130
-                      color: const Color(0xFF333333),
131
-                      fontSize: 17.sp,
132
-                      fontWeight: FontWeight.bold,
133
-                      letterSpacing: 2),
134
-                ),
135
-                Container(
136
-                  height: 54.h,
137
-                  alignment: Alignment.centerLeft,
138
-                  child: Row(
139
-                    children: [
140
-                      Expanded(
141
-                        flex: 1,
142
-                        child: TextField(
143
-                          controller: _cName,
144
-                          style: TextStyle(
145
-                              fontSize: 17.sp,
146
-                              fontWeight: FontWeight.bold,
147
-                              color: const Color(0xff333333)),
148
-                          decoration: const InputDecoration(
149
-                            isCollapsed: true,
150
-                            hintText: '请输入您的姓名',
151
-                            counterText: '', //去掉右下角的东西
152
-                            border: InputBorder.none,
153
-                            floatingLabelBehavior: FloatingLabelBehavior.never,
177
+                                fontWeight: FontWeight.bold,
178
+                                color: const Color(0xff333333)),
179
+                            decoration: const InputDecoration(
180
+                              isCollapsed: true,
181
+                              hintText: '请输入您的姓名',
182
+                              counterText: '', //去掉右下角的东西
183
+                              border: InputBorder.none,
184
+                              floatingLabelBehavior:
185
+                                  FloatingLabelBehavior.never,
186
+                            ),
187
+                            onChanged: (val) {
188
+                              name = val;
189
+                            },
190
+                            onTap: (){
191
+                              bindNewInputer(_userNameFocusNode);
192
+
193
+                            },
154 194
                           ),
155
-                          onChanged: (val) {
156
-                            name = val;
157
-                          },
158 195
                         ),
159
-                      ),
160
-                      GestureDetector(
161
-                        behavior: HitTestBehavior.opaque,
162
-                        onTap: () {
163
-                          name = '';
164
-                          _cName.clear();
165
-                        },
166
-                        child: Container(
167
-                          width: 50.w,
168
-                          alignment: Alignment.center,
169
-                          child: Image.asset(
170
-                            'images/main/cancel.png',
171
-                            width: 18.w,
196
+                        GestureDetector(
197
+                          behavior: HitTestBehavior.opaque,
198
+                          onTap: () {
199
+                            name = '';
200
+                            _cName.clear();
201
+                          },
202
+                          child: Container(
203
+                            width: 50.w,
204
+                            alignment: Alignment.center,
205
+                            child: Image.asset(
206
+                              'images/main/cancel.png',
207
+                              width: 18.w,
208
+                            ),
172 209
                           ),
173
-                        ),
174
-                      )
175
-                    ],
210
+                        )
211
+                      ],
212
+                    ),
176 213
                   ),
177
-                ),
178
-              ],
214
+                ],
215
+              ),
179 216
             ),
180
-          ),
181
-          Container(
182
-            width: 345.w,
183
-            alignment: Alignment.centerLeft,
184
-            margin: EdgeInsets.only(top: 40.h),
185
-            decoration: BoxDecoration(color: Colors.white, boxShadow: [
186
-              BoxShadow(color: Color(0x1f000000), offset: Offset(0, 1.w))
187
-            ]),
188
-            child: Column(
189
-              crossAxisAlignment: CrossAxisAlignment.start,
190
-              children: [
191
-                Text(
192
-                  '手机号:',
193
-                  style: TextStyle(
194
-                      color: const Color(0xFF333333),
195
-                      letterSpacing: 2,
196
-                      fontSize: 17.sp,
197
-                      fontWeight: FontWeight.bold),
198
-                ),
199
-                Container(
200
-                  height: 54.h,
201
-                  alignment: Alignment.centerLeft,
202
-                  child: Row(
203
-                    children: [
204
-                      Expanded(
205
-                        flex: 1,
206
-                        child: TextField(
207
-                          //赋初值
208
-                          controller: _cPhone,
209
-                          maxLength: 11,
210
-                          keyboardType: TextInputType.number,
211
-                          style: TextStyle(
212
-                              fontSize: 17.sp,
213
-                              fontWeight: FontWeight.bold,
214
-                              color: const Color(0xff333333)),
215
-                          decoration: const InputDecoration(
216
-                            isCollapsed: true,
217
-                            hintText: '请输入您的手机号',
218
-                            counterText: '', //去掉右下角的东西
219
-                            border: InputBorder.none,
220
-                            floatingLabelBehavior: FloatingLabelBehavior.never,
217
+            Container(
218
+              width: 345.w,
219
+              alignment: Alignment.centerLeft,
220
+              margin: EdgeInsets.only(top: 40.h),
221
+              decoration: BoxDecoration(color: Colors.white, boxShadow: [
222
+                BoxShadow(color: Color(0x1f000000), offset: Offset(0, 1.w))
223
+              ]),
224
+              child: Column(
225
+                crossAxisAlignment: CrossAxisAlignment.start,
226
+                children: [
227
+                  Text(
228
+                    '手机号:',
229
+                    style: TextStyle(
230
+                        color: const Color(0xFF333333),
231
+                        letterSpacing: 2,
232
+                        fontSize: 17.sp,
233
+                        fontWeight: FontWeight.bold),
234
+                  ),
235
+                  Container(
236
+                    height: 54.h,
237
+                    alignment: Alignment.centerLeft,
238
+                    child: Row(
239
+                      children: [
240
+                        Expanded(
241
+                          flex: 1,
242
+                          child: TextField(
243
+                            //赋初值
244
+                            controller: _cPhone,
245
+                            maxLength: 11,
246
+                            keyboardType: TextInputType.number,
247
+                            style: TextStyle(
248
+                                fontSize: 17.sp,
249
+                                fontWeight: FontWeight.bold,
250
+                                color: const Color(0xff333333)),
251
+                            decoration: const InputDecoration(
252
+                              isCollapsed: true,
253
+                              hintText: '请输入您的手机号',
254
+                              counterText: '', //去掉右下角的东西
255
+                              border: InputBorder.none,
256
+                              floatingLabelBehavior:
257
+                                  FloatingLabelBehavior.never,
258
+                            ),
259
+                            onChanged: (val) {
260
+                              phone = val;
261
+                            },
262
+                            onTap: () {
263
+                              // 点击时绑定当前focusNode
264
+                              bindNewInputer(_phoneFocusNode);
265
+                            },
221 266
                           ),
222
-                          onChanged: (val) {
223
-                            phone = val;
224
-                          },
225 267
                         ),
226
-                      ),
227
-                      GestureDetector(
228
-                        behavior: HitTestBehavior.opaque,
229
-                        onTap: () {
230
-                          phone = '';
231
-                          _cPhone.clear();
232
-                        },
233
-                        child: Container(
234
-                          width: 50.w,
235
-                          alignment: Alignment.center,
236
-                          child: Image.asset(
237
-                            'images/main/cancel.png',
238
-                            width: 18.w,
268
+                        GestureDetector(
269
+                          behavior: HitTestBehavior.opaque,
270
+                          onTap: () {
271
+                            phone = '';
272
+                            _cPhone.clear();
273
+                          },
274
+                          child: Container(
275
+                            width: 50.w,
276
+                            alignment: Alignment.center,
277
+                            child: Image.asset(
278
+                              'images/main/cancel.png',
279
+                              width: 18.w,
280
+                            ),
239 281
                           ),
240 282
                         ),
241
-                      ),
242
-                    ],
283
+                      ],
284
+                    ),
243 285
                   ),
244
-                ),
245
-              ],
286
+                ],
287
+              ),
246 288
             ),
247
-          ),
289
+            MyButton(
290
+                text: '保存',
291
+                type: 0,
292
+                pwith: 30.w,
293
+                disable: false,
294
+                onClick: () {
295
+                  handleOk();
296
+                })
297
+          ],
298
+        ),
299
+      ),
300
+    ];
301
+  }
302
+}
303
+
304
+
305
+class ScrollFocusNode extends FocusNode {
306
+  final bool _useSystemKeyBoard; // 是否使用系统键盘
307
+  final double _moveValue; // 上移距离
308
+
309
+  ScrollFocusNode(this._useSystemKeyBoard, this._moveValue);
310
+
311
+  @override
312
+  bool consumeKeyboardToken() {
313
+    if (_useSystemKeyBoard) {
314
+      return super.consumeKeyboardToken();
315
+    }
316
+    return false;
317
+  }
318
+
319
+  double get moveValue => _moveValue;
248 320
 
249
-          const Spacer(),
250
-          MyButton(
251
-              text: '保存',
252
-              type: 0,
253
-              pwith: 30.w,
254
-              disable: false,
255
-              onClick: () {
256
-                handleOk();
257
-              })
258
-        ],
321
+  bool get useSystemKeyBoard => _useSystemKeyBoard;
322
+}
323
+
324
+abstract class BoardWidget extends State<StatefulWidget>
325
+    with WidgetsBindingObserver {
326
+  final ScrollController _controller = ScrollController();
327
+
328
+  late ScrollFocusNode _focusNode;
329
+
330
+  double _currentPosition = 0.0;
331
+
332
+  List<Widget> initChild();
333
+
334
+  void bindNewInputer(ScrollFocusNode focusNode) {
335
+    _focusNode = focusNode;
336
+    _animateUp();
337
+  }
338
+
339
+  @override
340
+  void initState() {
341
+    super.initState();
342
+    WidgetsBinding.instance?.addObserver(this);
343
+  }
344
+
345
+  @override
346
+  void dispose() {
347
+    super.dispose();
348
+    _controller.dispose();
349
+    WidgetsBinding.instance?.removeObserver(this);
350
+  }
351
+
352
+  //  向上滚动
353
+  void _animateUp() {
354
+    _controller
355
+        .animateTo(_focusNode.moveValue,
356
+            duration: Duration(milliseconds: 250), curve: Curves.easeOut)
357
+        .then((Null) {
358
+      _currentPosition = _controller.offset;
359
+    });
360
+  }
361
+
362
+  //  向下滚动
363
+  void _animateDown() {
364
+    _controller
365
+        .animateTo(0.0,
366
+            duration: Duration(milliseconds: 250), curve: Curves.easeOut)
367
+        .then((Null) {
368
+      _currentPosition = 0.0;
369
+    });
370
+  }
371
+
372
+  @override
373
+  Widget build(BuildContext context) {
374
+    return Scaffold(
375
+      appBar: AppBar(
376
+        title: Text('个人信息'),
377
+      ),
378
+      backgroundColor: Colors.white,
379
+      body: SingleChildScrollView(
380
+        controller: _controller,
381
+        physics: NeverScrollableScrollPhysics(),
382
+        child: Column(
383
+          children: initChild()..add(SizedBox(height: 400.0)),
384
+        ),
259 385
       ),
260 386
     );
261 387
   }
388
+
389
+  //  使用系统键盘 ---> 矩阵变换 ---> 返回原位置
390
+  @override
391
+  void didChangeMetrics() {
392
+    if (_currentPosition != 0.0) {
393
+      _focusNode.unfocus(); // 如果不加,收起键盘再点击会默认键盘还在。
394
+      _animateDown();
395
+    }
396
+  }
262 397
 }

+ 1
- 1
lib/widgets/layout/BasicPage.dart 查看文件

@@ -103,11 +103,11 @@ class _BasicPageState extends State<BasicPage> {
103 103
   Widget build(BuildContext context) {
104 104
 
105 105
     return Scaffold(
106
-
107 106
       resizeToAvoidBottomInset: false,
108 107
       appBar: _getAppBar(),
109 108
       body: SafeArea(
110 109
         child: widget.builder(context),
110
+
111 111
       ),
112 112
       bottomNavigationBar: widget.tabIndex == null ? null : BottomBar(list: BarList, current: widget.tabIndex!),
113 113
     );