Flutter 车牌号/身份证等特殊输入框,以及通知传值
2020-10-21 本文已影响0人
技术混子
如上图,此类需求,需要特殊处理,由于本人很懒就自己写了一套: Container套text来实现此需求。
Top 1.
用 GridView.builder 来实现 那几个框框
GridView.builder(
shrinkWrap: true,
physics:
new NeverScrollableScrollPhysics(),
//禁止滑动
itemCount: 8,
//SliverGridDelegateWithFixedCrossAxisCount 构建一个横轴固定数量Widget
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
//横轴元素个数
crossAxisCount: 8,
//纵轴间距
mainAxisSpacing:
0.0,
//横轴间距
crossAxisSpacing:
5.0,
//子组件宽高长度比例
childAspectRatio:
15 / 20),
itemBuilder:
(BuildContext context,
int item) {
return Container(
width: 15,
height: 20,
decoration: BoxDecoration(
borderRadius:
BorderRadius
.circular(
5),
border: Border.all(
color: item ==
vecList.length -
1
? Color.fromRGBO(
39,
153,
93,
1)
: Color
.fromRGBO(
8,
8,
8,
1),
width: 1)),
child: Align(
alignment: Alignment
.center,
child: Text(
//用于解决 车牌号未输入完其余空展示
vecList.length ==
8
? vecList[
item]
: item <
vecList
.length
? vecList[
item]
: '',
style: TextStyle(
color: Color
.fromRGBO(
8,
8,
8,
1),
fontSize: 14),
),
),
);
}),
Top 2.
用 InkWell来做点击事件
InkWell( onTap: () {})
Top 3.
用showModalBottomSheet 展示仿键盘弹出样式
点击事件代码如下,利用list与string 的转换来展示信息
InkWell( onTap: () {
showModalBottomSheet(
barrierColor:
Color.fromRGBO(
255, 255, 255, 0),
isScrollControlled: true,
isDismissible: true,
enableDrag: false,
context: context,
builder: (BuildContext
context) {
return CarKeyboard(
type: ocrBool ? 1 : 0,
onChanged: (value) {
setState(() {
if (value ==
'del') {
if (vecList
.length >
0) {
vecList
.removeLast();
}
if (vecList
.length ==
0) {
ocrBool =
false;
//发送通知
NotificationCenter
.instance
.postNotification(
'change',
0);
}
} else {
ocrBool = true;
//车牌号展示 逻辑
if (vecList
.length <
8) {
vecList.add(
value);
}
}
//数组list转 string
String result;
vecList.forEach(
(string) => {
if (result ==
null)
result =
string
else
result =
'$result$string'
});
dataMap['vehicleLicence'] =
result;
print(
'回调车牌:$result');
});
},
);
},
);
},
Top 4.
CarKeyboard 封装代码
const PROVINCES = [
'京', '沪', '津', '渝', '冀','晋','蒙', '辽','吉','黑','苏','浙', '皖','闽','赣','鲁','豫', '鄂', '湘','粤','桂', '琼', '川', '贵', '云', '藏','陕', '甘','青','宁', '新'
];
const ALPHABETS = [
'A', 'B', 'C', 'D', 'E', 'F', 'G','H', 'I', 'J','K', 'L', 'M','N','O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V','W','X', 'Y', 'Z', '0', '1','2', '3', '4', '5','6','7','8','9',
'学', '警','挂',
];
class CarKeyboard extends StatefulWidget {
final ValueChanged<String> onChanged; //传值
final int type; //
const CarKeyboard({
Key key,
this.onChanged,
this.type,
}) : super(key: key);
@override
_CarKeyboardState createState() => _CarKeyboardState();
}
class _CarKeyboardState extends State<CarKeyboard> {
bool showBool = true;
@override
void initState() {
// TODO: implement initState
super.initState();
widget.type == 1 ? showBool = false : showBool = true;
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Container(
color: Color.fromRGBO(192, 198, 199, 0.7),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox(
height: 10,
),
Row(
children: [
SizedBox(
width: 10,
),
InkWell(
onTap: () {
Navigator.pop(context);
},
child: Container(
width: 50,
height: 40,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Color.fromRGBO(164, 170, 174, 1)),
child: Align(
alignment: Alignment.center,
child: Text(
'取消',
style: TextStyle(
color: Colors.black,
fontSize: 14,
fontWeight: FontWeight.bold),
),
)),
),
Expanded(child: SizedBox()),
Text(
'选择车牌号',
style: TextStyle(
color: Colors.black,
fontSize: 14,
fontWeight: FontWeight.bold),
),
Expanded(child: SizedBox()),
InkWell(
onTap: () {
widget.onChanged('del');
//添加监听者
NotificationCenter.instance.addObserver('change',
(object) {
setState(() {
if (object == 0) showBool = true;
if (object == 1) showBool = false;
//移除监听
NotificationCenter.instance
.removeNotification('change');
});
});
},
child: Container(
width: 50,
height: 40,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Color.fromRGBO(164, 170, 174, 1)),
child: Align(
alignment: Alignment.center,
child: Text(
'X',
style: TextStyle(
color: Colors.black,
fontSize: 14,
fontWeight: FontWeight.bold),
),
)),
),
SizedBox(
width: 10,
),
],
),
SizedBox(
height: 10,
),
Row(children: [
SizedBox(
width: 10,
),
Expanded(
child: GridView.builder(
shrinkWrap: true,
// physics: NeverScrollableScrollPhysics(),
//禁止滑动
itemCount:
showBool ? PROVINCES.length : ALPHABETS.length,
//SliverGridDelegateWithFixedCrossAxisCount 构建一个横轴固定数量Widget
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
//横轴元素个数
crossAxisCount: 7,
//纵轴间距
mainAxisSpacing: 10.0,
//横轴间距
crossAxisSpacing: 10.0,
//子组件宽高长度比例
childAspectRatio: 30 / 30),
itemBuilder: (BuildContext context, int item) {
return InkWell(
onTap: () {
setState(() {
widget.onChanged(showBool
? PROVINCES[item]
: ALPHABETS[item]);
if (showBool) {
showBool = false;
}
});
},
child: Container(
width: 30,
height: 30,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Colors.white),
child: Align(
alignment: Alignment.center,
child: Text(
showBool
? PROVINCES[item]
: ALPHABETS[item],
style: TextStyle(
color: Color.fromRGBO(8, 8, 8, 1),
fontSize: 14),
),
),
),
);
})),
SizedBox(
width: 10,
),
]),
SizedBox(
height: 10,
),
],
)));
}
}
ocrBool 用于点击时 甄别展示仿键盘样式
NotificationCenter 用于全部删除后的 仿键盘样式展示
//发送通知
NotificationCenter.instance .postNotification( 'change', 0);
通知的实现方式
封装一个公共类
//借鉴 前辈的 代码
typedef GetObject = Function(dynamic object);
class NotificationCenter {
// 工厂模式
factory NotificationCenter() => _getInstance();
static NotificationCenter get instance => _getInstance();
static NotificationCenter _instance;
NotificationCenter._internal() {
// 初始化
}
static NotificationCenter _getInstance() {
if (_instance == null) {
_instance = new NotificationCenter._internal();
}
return _instance;
}
//创建Map来记录名称
Map<String, dynamic> postNameMap = Map<String, dynamic>();
GetObject getObject;
//添加监听者方法
addObserver(String postName, object(dynamic object)) {
postNameMap[postName] = null;
getObject = object;
}
//发送通知传值
postNotification(String postName, dynamic object) {
//检索Map是否含有postName
if (postNameMap.containsKey(postName)) {
postNameMap[postName] = object;
getObject(postNameMap[postName]);
}
}
//移除通知
removeNotification(String postName) {
if (postNameMap.containsKey(postName)) {
postNameMap.remove(postName);
}
}
}
创建通知
//添加监听者
NotificationCenter.instance.addObserver('change',(object) {
setState(() { });
});
发送通知
//发送通知
NotificationCenter .instance .postNotification( 'change', 0);
移除通知
//移除监听
NotificationCenter.instance .removeNotification('change');
表达不是很好希望对各位有所帮助!!!