深度解析:ArkUI 中的自适应宽度输入框与点击保存功能 原创
引言
在日常的开发中,遇到需要更改用户名的UI设计,然而却遇到一些麻烦,比如用户名过长输入框不够怎么办,怎么去掉光标并保存输入等,在文档中查询还是很慢的,所以就对之前的困难做一个总结,本文将探讨如何使其宽度自适应、如何通过点击屏幕保存用户输入,以及如何去掉光标等技术细节。
输入框的基础设置
在 ArkUI 中,TextInput组件是用于接收用户输入的基本组件。下面我们将详细介绍如何设置这个组件的各种属性,以实现一个功能丰富且美观的输入框。
基本用法
TextInput({
'placeholder': "请输入标题",
'text': this.idCityTitleModel.title,
})
placeholder:设置输入框的占位符文本,当用户没有输入内容时,会显示这个文本。
text:设置输入框的初始文本内容,通常是通过状态管理来动态获取。
样式设置
.backgroundColor($r('app.color.background_color_lv3'))
.fontColor($r("app.color.main_font"))
.fontSize(24)
.width("auto")
.height(40)
.borderRadius(5)
.padding({ right: 5 })
- backgroundColor:设置输入框的背景颜色。
- fontColor:设置输入框中的字体颜色。
- fontSize:设置输入框中字体的大小。
- width:设置输入框的宽度,这里使用"auto"来实现宽度自适应。
- height:设置输入框的高度。
- borderRadius:设置输入框的圆角,使外观更加柔和。
- padding:设置输入框的内边距,以优化文本与边框的距离。
内容类型和输入类型
.type(InputType.USER_NAME)
.contentType(ContentType.USER_NAME)
type:设置输入框的输入类型,这里设置为USER_NAME,表示输入框用于输入用户名或标题。
contentType:设置输入框的内容类型,同样设置为USER_NAME,用于控制输入内容的过滤和验证。
光标样式
.caretStyle({ width: 1.5, color: '#000000' })
caretStyle:设置光标的宽度和颜色,这里将光标的宽度设置为1.5像素,颜色设置为黑色。
焦点状态
.focusable(this.isShowInput)
focusable:设置输入框是否可获得焦点,当this.isShowInput为true时,输入框才能获得焦点显示光标。可以将isShowInput绑定在任意位置即可。
取消按钮
.cancelButton({
style: CancelButtonStyle.CONSTANT,
icon: {
src: $r('app.media.bond_pen_svg'),
size: 16,
color: $r('app.color.menu_font_color')
}
})
cancelButton:设置取消按钮的样式和图标。这里使用了CONSTANT样式,表示取消按钮始终显示,并设置了图标的源、大小和颜色。注意这里的图片用svg,再设置颜色就可以填充,在深色模式也适配。和fillcolor类似
宽度自适应
在 ArkUI 中,我们可以通过将 width 属性设置为 “auto” 来让输入框的宽度根据其内容自动调整
.width("auto")
width(“auto”):该设置使得输入框的宽度根据输入的内容动态调整,而不是固定在一个特定的宽度值。这有助于在内容较短时节省空间,而在内容较长时自动扩展,从而提升用户体验。
说明:
在TextInput组件中,width设置auto表示自适应文本宽度。
在AlphabetIndexer组件中,width设置auto表示自适应宽度最大索引项的宽度。
在Row、Column、RelativeContainer组件中,width、height设置auto表示自适应子组件。
演示:
点击屏幕保存并去掉光标
基本功能介绍
点击屏幕保存功能允许用户在编辑输入框内容后,通过点击屏幕的其他区域来提交并保存更改。这一功能不仅提升了用户体验,还减少了用户的操作步骤。
实现点击屏幕保存的逻辑
为了实现点击屏幕保存的功能,我们需要在组件中添加一些逻辑和事件处理。以下是一个详细的实现步骤:
1. 设置光标状态:
使用 focusable 属性来控制输入框的焦点状态。
在点击输入框时,将 isShowInput 设置为 true,使其可获得焦点。
.onClick(() => {
this.isShowInput = true;
})
.focusable(this.isShowInput)
2. 监听全局点击事件
为了检测用户是否点击了屏幕的其他区域,我们需要在父组件的 Column 上监听 onClick 事件。
在父组件的 onClick 事件中,检查 isShowInput 的状态。
如果 isShowInput 为 true,则调用保存逻辑。
Column() {
TextInput({
'placeholder': "请输入标题",
'text': this.idCityTitleModel.title,
})
.onClick(() => {
this.isShowInput = true;
})
.onSubmit(async (EnterKeyType) => {
await this.saveRouteTitle();
})
.onChange((value: string) => {
this.routeTitle = value;
})
.focusable(this.isShowInput)
.cancelButton({
style: CancelButtonStyle.CONSTANT,
icon: {
src: $r('app.media.bond_pen_svg'),
size: 16,
color: $r('app.color.menu_font_color')
}
})
.backgroundColor($r('app.color.background_color_lv3'))
.type(InputType.USER_NAME)
.fontColor($r("app.color.main_font"))
.contentType(ContentType.USER_NAME)
.caretStyle({ width: 1.5, color: '#000000' })
.textAlign(TextAlign.Start)
.fontSize(24)
.width("auto")
.height(40)
.borderRadius(5)
.padding({ right: 5 })
.margin({ top: 100 })
}
.onClick(async () => {
if (this.idCityTitleModel.title == "" || this.idCityTitleModel.title == this.routeTitle) {
this.isShowInput = false;
return;
}
await updateRouteNickName(this.idCityTitleModel.routeId, this.routeTitle);
this.idCityTitleModel.title = this.routeTitle;
this.isShowInput = false;
})
.backgroundColor($r("app.color.background_color"))
.width('100%')
.height('100%')
3. 保存用户输入
在父组件的 onClick 事件中,检查 isShowInput 的状态。
如果 isShowInput 为 true,则调用保存逻辑。
private async saveRouteTitle() {
if (this.idCityTitleModel.title == "" || this.idCityTitleModel.title == this.routeTitle) {
this.isShowInput = false;
return;
}
await updateRouteNickName(this.idCityTitleModel.routeId, this.routeTitle);
this.idCityTitleModel.title = this.routeTitle;
this.isShowInput = false;
}
完整示例代码
import { router } from '@kit.ArkUI'
import { IdCityTitleModel } from '../models/LocationModel'
import { updateRouteNickName } from '../network/api/Route'
@Entry
@Component
export struct Test {
controller: TextInputController = new TextInputController()
@State idCityTitleModel: IdCityTitleModel = router.getParams() as IdCityTitleModel
@State isShowInput: boolean = false;
routeTitle: string = "";
private async saveRouteTitle() {
if (this.idCityTitleModel.title == "" || this.idCityTitleModel.title == this.routeTitle) {
this.isShowInput = false;
return;
}
await updateRouteNickName(this.idCityTitleModel.routeId, this.routeTitle);
this.idCityTitleModel.title = this.routeTitle;
this.isShowInput = false;
}
build() {
Column() {
TextInput({
'placeholder': "请输入标题",
'text': this.idCityTitleModel.title,
})
.onClick(() => {
this.isShowInput = true;
})
.onSubmit(async (EnterKeyType) => {
await this.saveRouteTitle();
})
.onChange((value: string) => {
this.routeTitle = value;
})
.focusable(this.isShowInput)
.cancelButton({
style: CancelButtonStyle.CONSTANT,
icon: {
src: $r('app.media.bond_pen_svg'),
size: 16,
color: $r('app.color.menu_font_color')
}
})
.backgroundColor($r('app.color.background_color_lv3'))
.type(InputType.USER_NAME)
.fontColor($r("app.color.main_font"))
.contentType(ContentType.USER_NAME)
.caretStyle({ width: 1.5, color: '#000000' })
.textAlign(TextAlign.Start)
.fontSize(24)
.width("auto")
.height(40)
.borderRadius(5)
.padding({ right: 5 })
.margin({ top: 100 })
}
.onClick(async () => {
await this.saveRouteTitle();
})
.backgroundColor($r("app.color.background_color"))
.width('100%')
.height('100%')
}
}
解释
- TextInput 的 onClick 事件:在输入框内点击时,将 isShowInput 设置为 true,使输入框可获得焦点。
- TextInput 的 onSubmit 事件:通过点击键盘的提交按钮(如“Enter”键)来保存用户输入的内容。
- 父组件的 onClick 事件:在父组件的 Column 上监听全局点击事件。如果 isShowInput 为 true,则调用 saveRouteTitle 方法来保存用户输入的内容。
- saveRouteTitle 方法:该方法负责检查用户输入的内容是否为空或与原有内容相同。如果不满足条件,则调用 updateRouteNickName 函数将新标题保存到服务器,并更新本地状态。
取消按钮图标自定义
取消按钮允许用户在编辑输入框内容时取消当前的编辑操作,返回到原始状态。通过自定义取消按钮的样式,可以使界面更加统一和美观。
.cancelButton({
style: CancelButtonStyle.CONSTANT,
icon: {
src: $r('app.media.bond_pen_svg'),
size: 16,
color: $r('app.color.menu_font_color')
}
})
详细请参考我的另一篇博客ArkUI框架下TextInput组件的右侧自定义图标设计指南:提升用户体验的艺术
总结
通过本文的解析,我们不仅了解了 ArkUI 中 TextInput 组件的基本用法和高级特性,还学习了如何提升用户体验和界面美观性。希望这些内容对你有所帮助,如果你有任何问题或建议,欢迎在评论区留言讨论。