在 Flutter 中创建自定义 NumPad(数字键盘)
- 2022 年 1 月 17 日
本文字数:5177 字
阅读完需:约 17 分钟
作者:坚果
公众号:"大前端之旅"
华为云享专家,InfoQ 签约作者,阿里云专家博主,51CTO 博客首席体验官,开源项目GVA成员之一,专注于大前端技术的分享,包括 Flutter,小程序,安卓,VUE,JavaScript。
介绍
在某些情况下,iOS 或 Android 上的默认软键盘无法满足您的需求,这个时候尝试调整或深度自定义默认软键盘是一个非常好的主意。
本文将向您展示如何在 Flutter 中实现自定义数字键盘。我们将在不使用任何第三方插件的情况下从头开始制作。可能代码有点长,大家不要介意。
应用预览
我们要做的小键盘有 9 个圆形按钮,用于输入 0 到 9 的数字。此外还有 2 个图标按钮:第一个按钮用于删除最后一个数字,另一个用于提交接收到的数字。按下提交按钮时,将显示一个带有结果的对话框。
以下是它的工作原理:
环境
代码
1.运行以下命令初始化一个新的 Flutter 项目:
flutter create custom_numpad_example
打开当前项目
cd custom_numpad_example
用 vscode 打开项目
code .
在 lib 目录中,添加一个名为 num_pad.dart 的新文件。该文件将保存我们可重用和可定制的 NumPad 小部件。lib 文件夹内的文件结构现在如下所示:
.
├── main.dart
└── num_pad.dart
2.将以下内容添加到 num_pad.dart 文件中:
import 'package:flutter/material.dart';
// KeyPad widget
// This widget is reusable and its buttons are customizable (color, size)
class NumPad extends StatelessWidget {
final double buttonSize;
final Color buttonColor;
final Color iconColor;
final TextEditingController controller;
final Function delete;
final Function onSubmit;
const NumPad({
Key? key,
this.buttonSize = 70,
this.buttonColor = Colors.indigo,
this.iconColor = Colors.amber,
required this.delete,
required this.onSubmit,
required this.controller,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(left: 30, right: 30),
child: Column(
children: [
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// implement the number keys (from 0 to 9) with the NumberButton widget
// the NumberButton widget is defined in the bottom of this file
children: [
NumberButton(
number: 1,
size: buttonSize,
color: buttonColor,
controller: controller,
),
NumberButton(
number: 2,
size: buttonSize,
color: buttonColor,
controller: controller,
),
NumberButton(
number: 3,
size: buttonSize,
color: buttonColor,
controller: controller,
),
],
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
NumberButton(
number: 4,
size: buttonSize,
color: buttonColor,
controller: controller,
),
NumberButton(
number: 5,
size: buttonSize,
color: buttonColor,
controller: controller,
),
NumberButton(
number: 6,
size: buttonSize,
color: buttonColor,
controller: controller,
),
],
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
NumberButton(
number: 7,
size: buttonSize,
color: buttonColor,
controller: controller,
),
NumberButton(
number: 8,
size: buttonSize,
color: buttonColor,
controller: controller,
),
NumberButton(
number: 9,
size: buttonSize,
color: buttonColor,
controller: controller,
),
],
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
// this button is used to delete the last number
IconButton(
onPressed: () => delete(),
icon: Icon(
Icons.backspace,
color: iconColor,
),
iconSize: buttonSize,
),
NumberButton(
number: 0,
size: buttonSize,
color: buttonColor,
controller: controller,
),
// this button is used to submit the entered value
IconButton(
onPressed: () => onSubmit(),
icon: Icon(
Icons.done_rounded,
color: iconColor,
),
iconSize: buttonSize,
),
],
),
],
),
);
}
}
// define NumberButton widget
// its shape is round
class NumberButton extends StatelessWidget {
final int number;
final double size;
final Color color;
final TextEditingController controller;
const NumberButton({
Key? key,
required this.number,
required this.size,
required this.color,
required this.controller,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
width: size,
height: size,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: color,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(size / 2),
),
),
onPressed: () {
controller.text += number.toString();
},
child: Center(
child: Text(
number.toString(),
style: const TextStyle(
fontWeight: FontWeight.bold, color: Colors.white, fontSize: 30),
),
),
),
);
}
}
3.最后但同样重要的是,在 main.dart 中创建我们的 NumPad 类的实例并使其工作:
// main.dart
import 'package:flutter/material.dart';
// import our custom number keyboard
import './num_pad.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: '大前端之旅',
theme: ThemeData(primarySwatch: Colors.amber),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
// text controller
final TextEditingController _myController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('大前端之旅'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// display the entered numbers
Padding(
padding: const EdgeInsets.all(20),
child: SizedBox(
height: 70,
child: Center(
child: TextField(
controller: _myController,
textAlign: TextAlign.center,
showCursor: false,
style: const TextStyle(fontSize: 40),
// Disable the default soft keybaord
keyboardType: TextInputType.none,
)),
),
),
// implement the custom NumPad
NumPad(
buttonSize: 75,
buttonColor: Colors.purple,
iconColor: Colors.deepOrange,
controller: _myController,
delete: () {
_myController.text = _myController.text
.substring(0, _myController.text.length - 1);
},
// do something with the input numbers
onSubmit: () {
debugPrint('Your code: ${_myController.text}');
showDialog(
context: context,
builder: (_) => AlertDialog(
content: Text(
"You code is ${_myController.text}",
style: const TextStyle(fontSize: 30),
),
));
},
),
],
),
);
}
}
结论
我们一起在 Flutter 中构建了一个自定义数字小键盘。您可以保存 num_pad.dart 文件并根据需要对其进行修改,以便在以后的项目中重复使用。
根据此灵感,你可以做出你的一个计算器应用吗?我想没问题的,加油!
最后大家觉得今天的内容如何呢?欢迎在留言区评论。
版权声明: 本文为 InfoQ 作者【坚果】的原创文章。
原文链接:【http://xie.infoq.cn/article/2ce126b1a7044d8458e4b3476】。文章转载请联系作者。
坚果
此间若无火炬,我便是唯一的光 2020.10.25 加入
公众号:“大前端之旅”,华为云享专家,InfoQ签约作者,51CTO博客首席体验官,专注于大前端技术的分享,包括Flutter,小程序,安卓,VUE,JavaScript。
评论