用getx實(shí)現(xiàn)的數(shù)字鍵盤
使用示例
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:demo_news/num_keyboard.dart';
class NewsPage3 extends GetView {
final PayNumKeyboardController _textEditingController = PayNumKeyboardController('');
final _resultData = ''.obs;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(""),
),
body: _buildBody(context),
);
}
Widget _buildBody(BuildContext context) {
return Column(
children: [
SizedBox(height: 60, width: MediaQuery.sizeOf(context).width),
Text(
'修改支付密碼',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
),
),
SizedBox(height: 10),
Text(
'請(qǐng)輸入原始支付密碼恤磷,以驗(yàn)證身份',
style: TextStyle(
fontSize: 15,
),
),
SizedBox(height: 20),
Obx(() {
return _buildNumberWidget(_resultData.value.length);
}),
Spacer(),
PayNumKeyboard(
controller: _textEditingController,
onChanged: (value) {
_resultData.value = value;
if (value.length == 6) {
_textEditingController.clearText();
_resultData.value = '';
// 接口校驗(yàn)
}
},
),
],
);
}
Widget _buildNumberWidget(int length) {
return Container(
height: 47,
width: 282,
child: ListView.builder(
padding: EdgeInsets.zero,
scrollDirection: Axis.horizontal,
physics: NeverScrollableScrollPhysics(),
itemCount: 6,
itemExtent: 47,
itemBuilder: (BuildContext context, int index) {
bool showPoint = index < length;
return _buildNumberItemWidget(index, showPoint);
},
),
);
}
Widget _buildNumberItemWidget(int index, bool showPoint) {
// 設(shè)置四周圓角 角度
BorderRadiusGeometry borderRadius = BorderRadius.only();
// 設(shè)置四周邊框
Color color = Colors.black12;
BorderSide borderSide0 = BorderSide(width: 0, color: color);
BorderSide borderSide05 = BorderSide(width: 0.5, color: color);
BoxBorder border = Border(top: borderSide05, left: borderSide05, bottom: borderSide05, right: borderSide0);
if (index == 0) {
borderRadius = BorderRadius.only(
topLeft: Radius.circular(4),
bottomLeft: Radius.circular(4),
);
border = Border(top: borderSide05, left: borderSide05, bottom: borderSide05, right: borderSide0);
} else if (index == 5) {
borderRadius = BorderRadius.only(
topRight: Radius.circular(4),
bottomRight: Radius.circular(4),
);
border = Border.all(width: 0.5, color: color);
}
return Container(
height: 47,
width: 47,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: borderRadius,
border: border,
),
child: showPoint
? Container(
height: 10,
width: 10,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(5),
),
)
: Container(),
);
}
}
鍵盤組件
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class PayNumKeyboard extends StatelessWidget {
final PayNumKeyboardController controller;
final ValueChanged<String> onChanged;
PayNumKeyboard({required this.controller, required this.onChanged, Key? key}) : super(key: key);
static const List<PayKeyboardDataBean> _keyboardDataList = [
PayKeyboardDataBean(PayKeyboardType.num, "1"),
PayKeyboardDataBean(PayKeyboardType.num, "2"),
PayKeyboardDataBean(PayKeyboardType.num, "3"),
PayKeyboardDataBean(PayKeyboardType.num, "4"),
PayKeyboardDataBean(PayKeyboardType.num, "5"),
PayKeyboardDataBean(PayKeyboardType.num, "6"),
PayKeyboardDataBean(PayKeyboardType.num, "7"),
PayKeyboardDataBean(PayKeyboardType.num, "8"),
PayKeyboardDataBean(PayKeyboardType.num, "9"),
PayKeyboardDataBean(PayKeyboardType.none, ""),
PayKeyboardDataBean(PayKeyboardType.num, "0"),
PayKeyboardDataBean(PayKeyboardType.delete, ""),
];
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: (125 / 54),
),
itemBuilder: (context, index) {
return buildNumKeyboardItem(_keyboardDataList[index]);
},
itemCount: _keyboardDataList.length,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
);
}
Widget buildNumKeyboardItem(PayKeyboardDataBean keyboardDataBean) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
if (keyboardDataBean.type == PayKeyboardType.delete) {
if (controller.value.length > 0) {
controller.value = controller.value.substring(0, controller.value.length - 1);
onChanged(controller.value);
}
} else if (keyboardDataBean.type == PayKeyboardType.num) {
controller.value += keyboardDataBean.value;
onChanged(controller.value);
}
},
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
color: keyboardDataBean.type == PayKeyboardType.num ? Colors.transparent : Colors.black12,
border: Border(
top: BorderSide(width: 0.5, color: Colors.black12),
right: BorderSide(width: 0.5, color: Colors.black12),
),
),
child: keyboardDataBean.type == PayKeyboardType.delete
? Image.asset('packages/demo_news/assets/images/keyboard_delete.png', width: 24, height: 24,)
: Text(
keyboardDataBean.value,
style: TextStyle(
fontSize: 20,
color: Colors.black,
),
),
),
);
}
}
enum PayKeyboardType {
none,
num,
delete,
}
class PayKeyboardDataBean {
final PayKeyboardType type;
final String value;
const PayKeyboardDataBean(this.type, this.value);
}
class PayNumKeyboardController extends RxString {
PayNumKeyboardController(super.initial);
void setText(String text) {
value = text;
}
void clearText() {
value = '';
}
}