Flutter创建自定义的软键盘

参考代码:

Flutter - Create Custom Keyboard Examples

本文贴出的代码实现了一个输入十六进制数据的键盘:

(1)支持长按退格键连续删除字符;

(2)可通过退格键删除选中的文字;

(3)监听文本变化(包括粘贴剪切导致的变化)。 

hex_keyboard.dart

import 'dart:async';import 'package:flutter/material.dart';class HexKeyboard extends StatefulWidget {final TextEditingController controller;final void Function() onDone;final void Function(String) onTextChanged;const HexKeyboard({super.key,required this.controller,required this.onDone,required this.onTextChanged,});@overrideState<HexKeyboard> createState() => _HexKeyboardState();
}class _HexKeyboardState extends State<HexKeyboard> {late TextEditingController _controller;final Widget _horizontalPadding = const SizedBox(width: 1.0);final Widget _verticalPadding = const SizedBox(height: 1.0);Timer? _timer;@overridevoid initState() {super.initState();_controller = widget.controller;}void _handleType(String text) {int position = _controller.selection.base.offset;var value = _controller.text;if (value.isEmpty) {_controller.text = text;} else {_controller.text = value.substring(0, position) +text +value.substring(position, value.length);}_controller.selection =TextSelection.fromPosition(TextPosition(offset: position + 1));widget.onTextChanged(_controller.text);}void _handleBackspace() {final value = _controller.text;if (value.isNotEmpty) {final start = _controller.selection.start;final end = _controller.selection.end;print("selection.start=$start, selection.end=$end");final int offset;if(end > 0) {if(start == end) {_controller.text = value.substring(0, start - 1) +value.substring(start, value.length);offset = start - 1;} else {_controller.text = value.substring(0, start) +value.substring(end, value.length);offset = start;}_controller.selection =TextSelection.fromPosition(TextPosition(offset: offset));widget.onTextChanged(_controller.text);}}}Widget _buildButton(String text,{VoidCallback? onPressed,VoidCallback? onLongPressStart,VoidCallback? onLongPressUp}) {return Expanded(child: Container(color: Colors.white,child: GestureDetector(onLongPressStart: (e) {onLongPressStart?.call();},onLongPressUp: onLongPressUp,child: TextButton(onPressed: onPressed ?? () => _handleType(text),child: Text(text,style: const TextStyle(color: Colors.black, fontSize: 16),),),),),);}@overrideWidget build(BuildContext context) {return _buildButtonKeyboard();}Widget _buildButtonRow(String key1, String key2, String key3) {return Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly,children: [_horizontalPadding,_buildButton(key1),_horizontalPadding,_buildButton(key2),_horizontalPadding,_buildButton(key3),_horizontalPadding,],);}Widget _buildButtonKeyboard() {return Container(color: const Color(0xffdddddd),child: Column(children: [_verticalPadding,_buildButtonRow('A', 'B', 'C'),_verticalPadding,_buildButtonRow('D', 'E', 'F'),_verticalPadding,_buildButtonRow('1', '2', '3'),_verticalPadding,_buildButtonRow('4', '5', '6'),_verticalPadding,_buildButtonRow('7', '8', '9'),_verticalPadding,Row(children: [_horizontalPadding,_buildButton('⌫',onPressed: _handleBackspace,onLongPressStart: () {_timer =Timer.periodic(const Duration(milliseconds: 50), (timer) {_handleBackspace();});},onLongPressUp: () {_timer?.cancel();},),_horizontalPadding,_buildButton('0'),_horizontalPadding,_buildButton('Done',onPressed: widget.onDone,),_horizontalPadding,],),_verticalPadding,],),);}
}

 hex_input_screen.dart

import 'package:flutter/material.dart';class HexInputScreen extends StatefulWidget {final String text;const HexInputScreen({super.key, required this.text});@overrideState<HexInputScreen> createState() => _HexInputScreenState();
}class _HexInputScreenState extends State<HexInputScreen> {late TextEditingController _controller;final FocusNode _focus = FocusNode();late ValueNotifier<bool> _focusValueNotifier;int _byteCount = 0;int _toByteCount(String hex) {return hex.length % 2 == 0 ? hex.length ~/ 2 : hex.length ~/ 2 + 1;}void _onTextChanged(String text) {//更新字节数setState(() {_byteCount = _toByteCount(text);});}@overridevoid initState() {_controller = TextEditingController(text: widget.text);_focus.addListener(_handleFocusChange);_focusValueNotifier = ValueNotifier<bool>(_focus.hasFocus);_focus.requestFocus();setState(() {_byteCount = widget.text.length;});super.initState();}@overridevoid dispose() {super.dispose();_focus.removeListener(_handleFocusChange);_focus.dispose();}void _handleFocusChange() {_focusValueNotifier.value = _focus.hasFocus;}void _onDone() {print(_controller.text);Navigator.pop(context, _controller.text);}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('HEX' /*, style: TextStyle(color: Colors.white)*/),// backgroundColor: Colors.black,),body: Column(mainAxisAlignment: MainAxisAlignment.start,children: [const SizedBox(height: 10),Text('已输入 $_byteCount 字节'),Padding(padding: const EdgeInsets.all(8.0),child: TextField(decoration: const InputDecoration(border: OutlineInputBorder(borderSide: BorderSide(color: Colors.grey,width: 1,),),),controller: _controller,keyboardType: TextInputType.none,focusNode: _focus,maxLines: 12,maxLength: 1024,onChanged: _onTextChanged,//这里监听粘贴剪切导致的变化),),const Spacer(),ListenableBuilder(listenable: _focusValueNotifier,builder: (BuildContext context, Widget? child) {return _focus.hasFocus? HexKeyboard(controller: _controller,onDone: _onDone,onTextChanged: _onTextChanged,//这里监听自定义键盘导致的变化): Container();},),],),);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/5098.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spark-机器学习(8)分类学习之随机森林

在之前的文章中&#xff0c;我们学习了分类学习之支持向量机决策树支持向量机&#xff0c;并带来简单案例&#xff0c;学习用法。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&a…

【论文阅读——基于拍卖的水平联邦学习后付款激励机制设计与声誉和贡献度测量】

1.原文名称 Auction-Based Ex-Post-Payment Incentive Mechanism Design for Horizontal Federated Learning with Reputation and Contribution Measurement 2.本文的贡献 我们提出了一种贡献度测量方法。我们建立了一个声誉系统。声誉易于下降&#xff0c;难以提高。结合声…

第6篇:创建Nios II工程之控制LED<一>

Q&#xff1a;还记得第1篇吗&#xff1f;设计简单的逻辑电路&#xff0c;控制DE2-115开发板上LED的亮与熄灭&#xff0c;一行Verilog HDL的assign赋值语句即可实现。本期开始创建Nios II工程&#xff0c;用C语言代码控制DE2-115开发板上的LED实现流水灯效果。 A&#xff1a;在…

Windows编译OpenCV及扩展模块

OpenCV官网只提供了OpenCV Windows 64位动态库且不包括扩展模块&#xff0c;如果需要32位动态库&#xff0c;或者需要扩展模块的功能&#xff0c;则需要下载源码进行编译。 1. 版本说明与下载地址 OpenCV下载 https://github.com/opencv/opencv/releases/tag/4.9.0 OpenCV扩展模…

企业选择内外网文件摆渡平台的常见三大误区

网络隔离技术现在已经广泛应用于企业安全管理中&#xff0c;企业使用逻辑隔离或物理隔离的方式将网络隔离为内外网进而隔绝外部有害网络攻击&#xff0c;保护内部重要数据资产&#xff0c;但网络隔离后企业仍存在数据交换的需求&#xff0c;此时就需要内外网文件摆渡平台来承担…

人工智能_大模型044_模型微调004_随机梯度下降优化_常见损失计算算法_手写简单神经网络_实现手写体识别---人工智能工作笔记0179

然后对于,梯度下降,为了让训练的速度更好,更快的下降,又做了很多算法,可以看到 这里要知道Transformer中最常用的Adam 和 AdamW这两种算法. 当然,这些算法都是用于优化神经网络中的参数,以最小化损失函数。下面我会尽量以通俗易懂的方式解释它们的原理和适用场景。 1. **L-…

selenium设置元素隐藏和显示

常见元素隐藏情况 在HTML中&#xff0c;由于页面美化和用户交互的需求&#xff0c;元素隐藏的使用非常常见&#xff0c;比如下拉菜单、内容折叠、对话框以及上传文件框等。隐藏常见有以下几种表现形式&#xff1a; hidden&#xff1a;占据空间&#xff0c;无法点击 style"…

Java成员内部类全解析:从创建、使用到优缺点分析

什么是成员内部类&#xff1f; 在Java的开发中&#xff0c;我们有时会遇到一种特殊的类&#xff0c;它并不像平常的类那样独立存在&#xff0c;而是寄生在另一个类的内部&#xff0c;这就是我们今天要讲的成员内部类。 成员内部类&#xff0c;顾名思义&#xff0c;是作为另一…

自然语言处理 (NLP) 和文本分析

自然语言处理 (NLP) 和文本分析&#xff1a;NLP 在很多领域都有着广泛的应用&#xff0c;如智能助手、语言翻译、舆情分析等。热门问题包括情感分析、命名实体识别、文本生成等。 让我们一起来详细举例子的分析讲解一下自然语言处理&#xff08;NLP&#xff09;和文本分析的应用…

BiLSTM-KDE的双向长短期记忆神经网络结合核密度估计多变量回归区间预测(Matlab)

BiLSTM-KDE的双向长短期记忆神经网络结合核密度估计多变量回归区间预测&#xff08;Matlab&#xff09; 目录 BiLSTM-KDE的双向长短期记忆神经网络结合核密度估计多变量回归区间预测&#xff08;Matlab&#xff09;效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.BiLS…

JAVA面试专题-Redis

你在最近的项目中哪些场景使用了Redis 缓存 缓存穿透 缓存穿透&#xff1a;查询一个不存在的数据&#xff0c;mysql查询不到数据也不好直接写入缓存&#xff0c;导致每次请求都查数据库。 解决方案一&#xff1a;缓存空数据&#xff0c;即使查询返回的数据为空&#xff0c;也把…

微信小程序开发核心:样式,组件,布局,矢量图标

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

MAC 本地搭建Dify环境

Dify 介绍 Dify 是一款开源的大语言模型(LLM) 应用开发平台。它融合了后端即服务&#xff08;Backend as Service&#xff09;和 LLMOps 的理念&#xff0c;使开发者可以快速搭建生产级的生成式 AI 应用。即使你是非技术人员&#xff0c;也能参与到 AI 应用的定义和数据运营过…

国内首个图计算平台团体标准发布,创邻科技参与编撰

2024年&#xff0c;由中国通信标准协会批准的团体标准《大数据 图计算平台技术要求与测试方法》&#xff08;编号&#xff1a;T/CCSA 470—2023&#xff09;&#xff08;下称&#xff1a;标准&#xff09;正式实施。该标准于1月4日在全国团体标准信息平台&#xff08;https://w…

超越GPT-4,清华发布网页导航智能体AutoWebGLM

随着大语言模型&#xff08;LLMs&#xff09;的发展&#xff0c;Agent在网络导航等任务中展现出了前所未有的能力。想象一下&#xff0c;一个基于LLM的Agent能够在你享用早餐时为你总结在线新闻&#xff0c;这样的场景已经不再遥不可及。这种将LLMs融入日常任务的做法&#xff…

AI小白使用Macbook Pro安装llama3与langchain初体验

1. 背景 AI爆火了2年有余&#xff0c;但我仍是一个AI小白&#xff0c;最近零星在学&#xff0c;随手记录点内容供自己复习。 上次在Macbook Pro上安装了Stable Diffusion&#xff0c;体验了本地所心所欲地生成各种心仪的图片&#xff0c;完全没有任何限制的惬意。今天想使用M…

Kafka客户端工具:Offset Explorer 使用指南

Kafka作为一个分布式流处理平台&#xff0c;在大数据处理和实时数据流应用中扮演着至关重要的角色。管理Kafka的topics及其offsets对于维护系统稳定性和数据一致性至关重要。Offset Explorer是一个强大的桌面应用程序&#xff0c;它使得管理和监控Kafka集群变得简单直观。本文将…

Ftrans文件外发系统 构建安全可控文件外发流程

文件外发系统是企业数据安全管理中的关键组成部分&#xff0c;它主要用于处理企业内部文件向外部传输的流程&#xff0c;确保数据在合法、安全、可控的前提下进行外发。 文件外发系统的主要作用包括&#xff1a; 1、防止数据泄露&#xff1a;通过严格的审批流程和安全策略&…

【JavaWeb】Day61.SpringBootWeb案例——配置文件

配置文件 参数配置化 在我们之前编写的程序中进行文件上传时&#xff0c;需要调用AliOSSUtils工具类&#xff0c;将文件上传到阿里云OSS对象存储服务当中。而在调用工具类进行文件上传时&#xff0c;需要一些参数&#xff1a; - endpoint //阿里云OSS域名 - accessKey…

JAVA基础---Stream流

Stream流出现背景 背景 在Java8之前&#xff0c;通常用 fori、for each 或者 Iterator 迭代来重排序合并数据&#xff0c;或者通过重新定义 Collections.sorts的 Comparator 方法来实现&#xff0c;这两种方式对 大数量系统来说&#xff0c;效率不理想。 Java8 中添加了一个…