Android低代码开发 - InputMenuPanelItem详解

我们知道MenuPanel是一个菜单面板容器,它里面可以放各式各样的菜单和菜单组。今天我们就来详细讲解输入菜单这个东西。

InputMenuPanelItem源码

package dora.widget.panel.menuimport android.content.Context
import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.LinearLayout
import dora.widget.panel.R
import dora.widget.panel.MenuPanelItem
import dora.widget.panel.MenuPanelItemRoot
import dora.widget.panel.MenuPanelItemRoot.Companion.DEFAULT_MARGIN_TOP
import dora.widget.panel.MenuPanelItemRoot.Companion.DEFAULT_TITLE_SPANclass InputMenuPanelItem@JvmOverloads constructor(override var marginTop: Int = DEFAULT_MARGIN_TOP,override var title: String? = "",private var titleSpan: MenuPanelItemRoot.Span = MenuPanelItemRoot.Span(DEFAULT_TITLE_SPAN),override val menuName: String? = MenuPanelItem.generateMenuName("InputMenuPanelItem"),private val hint: String?  = "",private val content: String? = "",private val watcher: ContentWatcher? = null
) : MenuPanelItem {constructor(title: String, titleSpan: MenuPanelItemRoot.Span, hint: String,content: String, watcher: ContentWatcher? = null) : this(DEFAULT_MARGIN_TOP,title, titleSpan, MenuPanelItem.generateMenuName("InputMenuPanelItem"),hint, content, watcher)constructor(title: String, titleSpan: MenuPanelItemRoot.Span, hint: String,content: String) : this(title, titleSpan, hint, content, null)constructor(hint: String,content: String, watcher: ContentWatcher? = null) : this(DEFAULT_MARGIN_TOP,"", MenuPanelItemRoot.Span(DEFAULT_TITLE_SPAN), MenuPanelItem.generateMenuName("InputMenuPanelItem"),hint, content, watcher)constructor(hint: String,content: String) : this(hint, content, null)override fun initData(menuView: View) {val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT)lp.topMargin = marginTopmenuView.layoutParams = lpval editText = menuView.findViewById<EditText>(ID_EDIT_TEXT_INPUT)editText.hint = hintif (!TextUtils.isEmpty(content)) {editText.setText(content)editText.setSelection(content!!.length)}if (watcher != null) {editText.addTextChangedListener(object : TextWatcher {override fun beforeTextChanged(s: CharSequence,start: Int,count: Int,after: Int) {}override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {watcher.onContentChanged(this@InputMenuPanelItem, s.toString())}override fun afterTextChanged(s: Editable) {}})}}override fun hasTitle(): Boolean {return title != null && title != ""}override fun getTitleSpan(): MenuPanelItemRoot.Span {return titleSpan}override fun setTitleSpan(titleSpan: MenuPanelItemRoot.Span) {this.titleSpan = titleSpan}override val layoutId: Intget() = R.layout.layout_menu_panel_inputoverride fun inflateView(context: Context): View {return LayoutInflater.from(context).inflate(layoutId, null)}interface ContentWatcher {fun onContentChanged(item: InputMenuPanelItem, content: String)}companion object {@JvmFieldval ID_EDIT_TEXT_INPUT: Int = R.id.et_menu_panel_input}
}

属性解析

marginTop:上边距

title和titleSpan:标题和标题边距

menuName:菜单名称,在同一个MenuPanel保证唯一性

hint:输入提示信息,同android:hint

content:输入内容,同android:text

watcher:输入观察者,用来监听输入的字符

使用场景

  • 场景1,6个属性都传入,完全自定义
  • 场景2,只指定hint和content,其他用默认
  • 场景3,在场景2的基础上增加一个输入字符监听器
  • 场景4,指定标题、标题边距、hint和content
  • 场景5,在场景4的基础上再增加一个输入字符监听器

IMAGE 2024-06-13 16:24:44.jpg

在这幅图中,就用到了几次InputMenuPanelItem。position分别为1、3、4和5。

InputMenuPanelItem相较于直接使用EditText的优势

  1. 可以给输入框指定一个标题提示信息,而不同于hint,用户可以一直看到。同时它可以和hint一起使用,让hint显示校验规则等其他信息。
  2. 可以快捷的添加到MenuPanel,而不用考虑布局,写一大堆的属性,仅指定几个关键属性。

使用说明书

是否需要指定menuName

不需要。我们知道,menuName作为MenuPanelItem的核心属性,需要保证其不重复,这样方便于我们找到它,并做相应的处理,如设置菜单的点击事件。但是在InputMenuPanelItem中,它的情况比较特殊,通常我们是不需要处理输入框的点击事件的。

所以框架在改进的过程中,最大限度的提供包容性。


companion object {/*** 虽然用它生成了默认的menuName,但是不建议你使用,最好使用业务的命名覆盖它。*/fun generateMenuName(prefix: String? = null) : String {val uuid = UUID.randomUUID().toString()return if (!TextUtils.isEmpty(prefix)) {prefix + "-" + uuid.replace("-".toRegex(), "")} else {uuid.replace("-".toRegex(), "")}}
}

注释虽然这么写,但是它不是针对InputMenuPanelItem的。我们建议你就直接使用框架生成的menuName,所以构造函数都没有让你指定menuName,当然你也可以指定它。在InputMenuPanelItem中,默认的menuName它是一个“InputMenuPanelItem-”再加上随机字符串。

获取到InputMenuPanelItem里面的EditText

getCacheChildView()

推荐使用它,通过position和view的id去拿到。id有一个常量,InputMenuPanelItem.ID_EDIT_TEXT_INPUT,可以直接使用,避免你导R包冲突,要写一长串的包名。

companion object {@JvmFieldval ID_EDIT_TEXT_INPUT: Int = R.id.et_menu_panel_input
}
getCacheViewFromItem()

也可以使用它,需要你传入一个MenuPanelItem的属性先拿到根布局,再通过findViewById()进行查找。

设置最大长度限制和输入的字符限制

拿到了EditText我们要给它设置限制条件就方便了。

android:maxLength代码指定

如设置最多输入10个字符。

etInput.filters = arrayOf(InputFilter.LengthFilter(10))
android:digits代码指定

如设置只能输入数字。

etInput.keyListener = DigitsKeyListener.getInstance("0123456789")
组合使用

只能输入2位的正整数。

etInput.filters = arrayOf(InputFilter.LengthFilter(2), object : InputFilter {override fun filter(source: CharSequence?,start: Int,end: Int,dest: Spanned?,dstart: Int,dend: Int): CharSequence? {try {val input = Integer.parseInt(dest.toString() + source.toString())if (input <= 0) {return ""; // 输入的数字小于或等于0,返回空字符串}} catch (e: NumberFormatException) {return ""; // 输入的不是数字,返回空字符串}return null}
})
etInput.keyListener = DigitsKeyListener.getInstance("0123456789")

在这个案例中,你不设置DigitsKeyListener也是可以保证只输入两位的正整数的,但是有个问题就是,输入法默认不给你显示数字输入键盘,需要手动切换。

定制输入框界面

如设置多行输入,自定义光标。

etInput.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,DensityUtils.dp2px(300f)
)
etInput.gravity = Gravity.TOP
etInput.isSingleLine = false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {etInput.textCursorDrawable = resources.getDrawable(R.drawable.edit_text_bg)
}

背景也可以定制,当然我们一般不这样做,有悖于框架的UI风格,哈哈。

MenuPanel的后期改进规划

  • 提供更多的MenuPanelItem
  • 可通过menuName获取到MenuPanelItem,当然这个API对于InputMenuPanelItem来说并没有什么用
  • 提供更贴心的构造函数,让使用者在用的时候可以少传参

总结

不管怎么说,输入菜单InputMenuPanelItem都是一个举足轻重的核心菜单项,对于它的优化,可不能马虎。MenuPanel遵循低代码设计理念,目的是为了让大家写代码就像拼积木一样,把能想到的尽可能多的考虑到,写代码就跟玩一样。

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

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

相关文章

系统集成项目管理工程师第9章思维导图发布

今天发布系统集成项目管理工程师新版第9章脑图的图片版

Nintex流程平台引入生成式人工智能,实现自动化革新

工作流自动化提供商Nintex宣布在其Nintex流程平台上推出一系列新的人工智能驱动改进。这些增强显著减少了文档化、管理和自动化业务流程所需的时间。这些新特性为Nintex流程平台不断扩展的人工智能能力增添了新的亮点。 Nintex首席产品官Niranjan Vijayaragavan表示&#xff1a…

使用React和GraphQL进行CRUD:完整教程与示例

在本教程中&#xff0c;我们将向您展示如何使用GraphQL和React实现简单的端到端CRUD操作。我们将介绍使用React Hooks读取和修改数据的简单示例。我们还将演示如何使用Apollo Client实现身份验证、错误处理、缓存和乐观UI。 什么是React&#xff1f; React是一个用于构建用户…

用python纯手写一个日历

一、代码 # 月份名称数组 months ["January", "February", "March", "April", "May", "June","July", "August", "September", "October", "November", &qu…

【Python/Pytorch - 网络模型】-- TV Loss损失函数

文章目录 文章目录 00 写在前面01 基于Pytorch版本的TV Loss代码02 论文下载 00 写在前面 在医学图像重建过程中&#xff0c;经常在代价方程中加入TV 正则项&#xff0c;该正则项作为去噪项&#xff0c;对于重建可以起到很大帮助作用。但是对于一些纹理细节要求较高的任务&am…

20.1 JSON-JSON接口以及在Go语言中使用JSON

1. 简介 JSON即JavaScript对象表示法(JavaScript Object Notation)&#xff0c;是一种用于存储和交换数据的格式&#xff0c;是一种可供人类阅读和理解的纯文本格式。 JSON既可以键值对的形式&#xff0c;也可以数组的形式&#xff0c;表示数据。 JSON最初是JavaScript的一个…

流媒体传输协议HTTP-FLV、WebSocket-FLV、HTTP-TS 和 WebSocket-TS的详细介绍、应用场景及对比

一、前言 HTTP-FLV、WS-FLV、HTTP-TS 和 WS-TS 是针对 FLV 和 TS 格式视频流的不同传输方式。它们通过不同的协议实现视频流的传输&#xff0c;以满足不同的应用场景和需求。接下来我们对这些流媒体传输协议进行剖析。 二、传输协议 1、HTTP-FLV 介绍&#xff1a;基于 HTTP…

【宠粉赠书】科研绘图神器:MATLAB科技绘图与数据分析

小智送书第二期~ 为了回馈粉丝们的厚爱&#xff0c;今天小智给大家送上一套科研绘图的必备书籍——MATLAB科技绘图与数据分析。下面我会详细给大家介绍这套图书&#xff0c;文末留有领取方式。 图书介绍 《MATLAB科技绘图与数据分析》是一本综合性强、内容丰富的书籍&#x…

实践分享:鸿蒙跨平台开发实例

先来理解什么是跨平台 提到跨平台&#xff0c;要先理解什么是“平台”&#xff0c;这里的平台&#xff0c;就是指应用程序的运行环境&#xff0c;例如操作系统&#xff0c;或者是Web浏览器&#xff0c;具体的像HarmonyOS、Android、iOS、或者浏览器&#xff0c;都可以叫做平台…

Python读取wps中的DISPIMG图片格式

需求&#xff1a; 读出excel的图片内容&#xff0c;这放在微软三件套是很容易的&#xff0c;但是由于wps的固有格式&#xff0c;会出现奇怪的问题&#xff0c;只能读出&#xff1a;类似于 DISPIMG(“ID_2B83F9717AE1XXXX920xxxx644C80DB1”,1) 【该DISPIMG函数只有wps才拥有】 …

阿里云服务器-Linux搭建fastDFS文件服务器

阿里云官网购买服务器&#xff0c;一般会有降价活动&#xff0c;这两天就发现有活动&#xff0c;99计划活动&#xff08;在活动期内&#xff0c;续费都是99元&#xff09; 阿里云官网-云服务器ECS 在这里&#xff0c;我购买了这台服务器&#xff0c;活动期内续费每年99元&…

javaweb 期末复习

1. JDBC数据库连接的实现逻辑与步骤以及JDBC连接配置&#xff08;单列模式&#xff09; public class JDBCUtil {// 这些换成自己的数据库 private static final String DB_URL "jdbc:mysql://localhost:3306/你的数据库名称";private static final String USER &q…

10分钟部署一个个人博客

关于vuepress这里没必要过多介绍&#xff0c;感兴趣的可以直接去官网了解&#xff0c;下面是官网首页地址截图 &#xff1a;https://v2.vuepress.vuejs.org/zh/ 透过这张图&#xff0c;我们也可以大致的对这个框架的特点有一定的认识&#xff0c;这就够了。其他的东西我们在使用…

vue3+ Element-Plus 点击勾选框往input中动态添加多个tag

实现效果&#xff1a; template&#xff1a; <!--产品白名单--><div class"con-item" v-if"current 0"><el-form-item label"平台名称"><div class"contaion" click"onclick"><!-- 生成的标签 …

WPF界面设计

1、使用C#-WPF实现抽屉效果-炫酷漂亮的侧边栏导航菜单-SplitViewMD主题重绘原生控件的美观效果-提供源码Demo下载 码源地址&#xff1a;https://download.csdn.net/download/Prince999999/89424685 2、使用C#-WPF实现抽屉效果-菜单导航功能实现&#xff0c;常规的管理系统应该…

使用itextPDF实现PDF电子公章工具类

一、制作公章 在线网站&#xff1a;印章生成器 - Kalvin在线工具 (kalvinbg.cn) 然后对公章进行下载保存 盖章图片&#xff1a; 二、生成数字签名 2.1&#xff1a; java工具keytool生成p12数字证书文件 Keytool是用于管理和证书的工具&#xff0c;位于%JAVA_HOME%/bin目录。…

【Python】Python 2 测试网络连通性脚本

文章目录 前言1. 命令行传参2. 代码 前言 最近在只有python2的服务器上部署服务&#xff0c;不能用三方类库&#xff0c;这里出于好奇心学习下python。这里简单做个脚本&#xff0c;实现了检验网络连通性的功能&#xff08;类似于curl&#xff09;。 1. 命令行传参 使用命令…

和鲸科技执行总裁殷自强:面向空间数据协同分析场景的模型生命周期管理方法

导读&#xff1a; 由 ACM SIGSPATIAL 中国分会主办的第五届空间数据智能学术会议&#xff08;SpatialDI 2024&#xff09;于 2024 年 4 月 25 日- 27 日在南京圆满召开&#xff0c;主题为“ AGI 时代下的空间数据智能”&#xff0c;旨在深入推动空间数据智能研究的理论进步与应…

TIM—通用定时器高级定时器

通用/高级定时器的功能 在基本定时器功能的基础上新增功能&#xff1a; 通用定时器有4个独立通道&#xff0c;且每个通道都可以用于下面功能。 &#xff08;1&#xff09;输入捕获&#xff1a;测量输入信号的周期和占空比等。 &#xff08;2&#xff09;输出比较&#xff1a;产…

115.网络游戏逆向分析与漏洞攻防-邮件系统数据分析-调试优化结构体类型数据的创建

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 现在的代码都是依据数据包来写的&#xff0c;如果看不懂代码&#xff0c;就说明没看懂数据包…