Android CustomTextField

news2025/2/26 6:16:11

在 Compose 中开发用户界面时,需要处理输入框和键盘的交互,例如在键盘弹出时调整布局位置,避免遮挡重要内容。本篇博客将通过一个完整的示例展示如何实现这一功能。

功能概述

本例实现了一个简单的输入框。当输入框获得焦点或输入文字时,以下行为发生:

  1. 键盘弹出。

  2. 输入框上方的占位符文本根据焦点状态和输入内容动态显示或隐藏。

  3. 整个布局根据键盘的弹出状态自动调整,避免内容被遮挡。

代码实现

封装TextField代码:
@Composable
fun CustomTextField(placeholderText: String, imageVector: Any) {
    // 定义状态变量管理输入框的文本和焦点状态
    var textValue by remember { mutableStateOf("") }
    var isTextFieldFocused by remember { mutableStateOf(false) }

    // 获取焦点管理器和键盘控制器
    val focusManager = LocalFocusManager.current
    val keyboardController = LocalSoftwareKeyboardController.current

    // 动态计算底部间距,键盘弹出时调整布局
    val bottomPadding by animateDpAsState(
        targetValue = if (isTextFieldFocused || textValue.isNotEmpty()) 40.dp else 16.dp
    )

    // 使用 Box 包裹输入框和占位符文本
    Box {
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .height(70.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Bottom
        ) {
            // 输入框组件
            Row(
                modifier = Modifier
                    .border(1.dp, Color.Black, RoundedCornerShape(16.dp))
                    .clip(RoundedCornerShape(16.dp))
                    .padding(0.dp) // 确保内边距为 0,避免额外的间距
            ) {
                // 在 TextField 前添加图标,根据传入的 imageVector 参数显示不同图标
                Icon(
                    imageVector = imageVector as androidx.compose.ui.graphics.vector.ImageVector,
                    contentDescription = "Icon",
                    modifier = Modifier
                        .size(35.dp)
                        .padding(
                            start = 10.dp,
                            top = 15.dp,
                            end = 0.dp,
                            bottom = 0.dp
                        )
                )

                TextField(
                    value = textValue,
                    onValueChange = { newText ->
                        textValue = newText
                    },
                    modifier = Modifier
                        .width(300.dp)
                        .height(50.dp)
                        .onFocusChanged { focusState ->
                            isTextFieldFocused = focusState.isFocused
                        },
                    keyboardOptions = KeyboardOptions.Default.copy(
                        imeAction = ImeAction.Done
                    ),
                    keyboardActions = KeyboardActions(
                        onDone = {
                            isTextFieldFocused = false
                            focusManager.clearFocus()
                        }
                    )
                )
            }
        }

        Column(
            modifier = Modifier
                .fillMaxWidth()
                .height(70.dp),
            horizontalAlignment = Alignment.Start,
            verticalArrangement = Arrangement.Bottom
        ) {
            // 占位符文本
            Text(
                text = placeholderText,
                modifier = Modifier
                    .padding(
                        start = 40.dp,
                        top = 0.dp,
                        end = 0.dp,
                        bottom = bottomPadding
                    )
                    .background(Color(235, 226, 241)),
                color = Color.Gray
            )
        }
    }
}

界面逻辑代码:

@Composable
fun BoxAlignmentExample() {
    // 设置 Surface 作为背景容器,填充整个屏幕
    Surface(
        modifier = Modifier
            .fillMaxWidth()
            .fillMaxHeight(),
        color = Color(235, 226, 241)
    ) {
        // 使用 Column 布局排列内容
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(16.dp),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Top
        ) {
            // name
            CustomTextField(placeholderText = " 请输入账号 ", imageVector = Icons.Default.Person)

            // password
            CustomTextField(placeholderText = " 请输入密码 ", imageVector = Icons.Default.Lock)
        }
    }
}

核心实现

  1. 状态管理 使用 remember 和 mutableStateOf 管理输入框文本内容 (textValue) 和焦点状态 (isTextFieldFocused)。

  2. 动画效果 借助 animateDpAsState 动态调整布局底部间距 bottomPadding,为界面变化提供平滑过渡。

  3. 输入框的焦点处理

    • 使用 onFocusChanged 检测输入框的焦点状态,更新 isTextFieldFocused

    • 在键盘输入完成时,通过 focusManager.clearFocus() 和 keyboardController?.hide() 收起键盘。

  4. 占位符文本逻辑

    • 如果输入框内容为空且未聚焦,显示占位符。

    • 根据状态动态调整占位符的显示位置和样式。

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

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

相关文章

【韩顺平Java笔记】第8章:面向对象编程(中级部分)【338-342】

338. 零钱通消费 package com.masterspark.smallchange;import java.text.SimpleDateFormat; import java.util.Date; import java.util.Scanner;public class SmallChangeSys {public static void main(String[] args) {//1. 先完成显示菜单,并可以选择菜单&#…

Mac M1处理器uiautomatorviewer 使用

问题 Android自带工具uiautomatorviewer在mac电脑上运行报错 解决 有位大神解决了这个问题 项目网址:https://github.com/TarCV/uiautomatorviewer-gradle ./gradlew installDist JAVA_OPTS-XstartOnFirstThread ./build/install/uiautomatorviewer-gradle/bin…

【漫话机器学习系列】054.极值(Extrema)

极值(Extrema) 定义 极值是数学分析和优化问题中的一个核心概念,指函数在某个定义域内取得的最大值或最小值。根据极值的性质,可以将其分为两类: 局部极值(Local Extrema):函数在…

QT开发技术 【基于TinyXml2的对类进行序列化和反序列化】一

一、对TinyXml2 进行封装 使用宏 实现序列化和反序列化 思路: 利用宏增加一个类函数,使用序列化器调用函数进行序列化 封装宏示例 #define XML_SERIALIZER_BEGIN(ClassName) \ public: \virtual void ToXml(XMLElement* parentElem, bool bSerialize …

代码随想录训练营第五十一天| 99.岛屿数量 深搜 岛屿数量 广搜 100.岛屿的最大面积

99.岛屿数量 深搜 题目链接:99. 岛屿数量 讲解链接:代码随想录 就是dfs模版题目 在dfs里可以先定义方向数组移动 再遍历分别向四个方向移动 同时记得更新当前nextx nexty 再判断是否越界 再执行判断条件 当前位置未走过 visited[i][j] false 一开始jav…

【HarmonyOS之旅】基于ArkTS开发(二) -> UI开发之常见布局

目录 1 -> 自适应布局 1.1 -> 线性布局 1.1.1 -> 线性布局的排列 1.1.2 -> 自适应拉伸 1.1.3 -> 自适应缩放 1.1.4 -> 定位能力 1.1.5 -> 自适应延伸 1.2 -> 层叠布局 1.2.1 -> 对齐方式 1.2.2 -> Z序控制 1.3 -> 弹性布局 1.3.1…

docker 部署 MantisBT

1. docker 安装MantisBT docker pull vimagick/mantisbt:latest 2.先运行实例,复制配置文件 docker run -p 8084:80 --name mantisbt -d vimagick/mantisbt:latest 3. 复制所需要配置文件到本地路径 docker cp mantisbt:/var/www/html/config/config_inc.php.…

【Linux系统编程】—— 深度解析进程等待与终止:系统高效运行的关键

文章目录 进程创建再次认识fork()函数fork()函数返回值 写时拷贝fork常规⽤法以及调用失败的原因 进程终⽌进程终止对应的三种情况进程常⻅退出⽅法_exit函数exit函数return退出 进程等待进程等待的必要性进程等待的⽅法 进程创建 再次认识fork()函数 fork函数初识&#xff1…

学习MyBatis的调优方案

MyBatis是一款优秀的Java持久层框架,它简化了数据库操作,并提供了灵活的SQL查询机制。然而,在实际应用中,我们可能会遇到一些性能问题,这时需要对MyBatis进行合理的调优。本文将详细探讨MyBatis的调优方案,…

python_在钉钉群@人员发送消息

python_在钉钉群人员发送消息 1、第一种 企业内部机器人群聊实现人接入指南,适用于群机器人接收消息,处理完一系列的动作之后,将消息返回给发消息的人员,同时该人员。 需要在企微后台新建一个自建应用,在自建应用里…

【Linux】进程优先级与进程切换

🔥个人主页🔥:孤寂大仙V 🌈收录专栏🌈:Linux 🌹往期回顾🌹:【Linux】进程状态 🔖流水不争,争的是滔滔不 一、进程优先级是什么二、查看系统进程三…

imbinarize函数用法详解与示例

一、函数概述 众所周知,im2bw函数可以将灰度图像转换为二值图像。但MATLAB中还有一个imbinarize函数可以将灰度图像转换为二值图像。imbinarize函数是MATLAB图像处理工具箱中用于将灰度图像或体数据二值化的工具。它可以通过全局或自适应阈值方法将灰度图像转换为二…

电商项目高级篇08-springCache

电商项目高级篇08-springCache 1、整合springCache2、Cacheable细节设置 1、整合springCache 1、引入依赖 <!--引入springCache--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifa…

macOS 安装JDK17

文章目录 前言介绍新特性下载安装1.下载完成后打开downloads 双击进行安装2.配置环境变量3.测试快速切换JDK 小结 前言 近期找开源软件&#xff0c;发现很多都已经使用JDK17springboot3 了&#xff0c;之前的JDK8已经被替换下场&#xff0c;所以今天就在本机安装了JDK17&#…

ASP.NET Core - 配置系统之配置提供程序

ASP.NET Core - 配置系统之配置提供程序 3. 配置提供程序3.1 文件配置提供程序3.1.1 JSON配置提供程序3.1.2 XML配置提供程序3.1.3 INI配置提供程序 3.2 环境变量配置提供程序3.3 命令行配置提供程序3.4 内存配置提供程序3.5 配置加载顺序 3.6 默认配置来源 3. 配置提供程序 前…

[手机Linux] ubuntu 错误解决

Ubuntu: 1,ttyname failed: Inappropriate ioctl for device 将 /root/.profile 文件中的 mesg n || true 改为如下内容。 vim /root/.profile tty -s && mesg n || true 2,Errors were encountered while processing: XXX XXXX sudo apt-get --purge remove xxx…

【2024年华为OD机试】 (B卷,100分)- 敏感字段加密(Java JS PythonC/C++)

一、问题描述 题目描述 给定一个由多个命令字组成的命令字符串&#xff1a; 字符串长度小于等于 127 字节&#xff0c;只包含大小写字母、数字、下划线和偶数个双引号&#xff1b;命令字之间以一个或多个下划线 _ 进行分割&#xff1b;可以通过两个双引号 "" 来标…

使用 ChatGPT 生成和改进你的论文

文章目录 零、前言一、操作引导二、 生成段落或文章片段三、重写段落四、扩展内容五、生成大纲内容六、提高清晰度和精准度七、解决特定的写作挑战八、感受 零、前言 我是虚竹哥&#xff0c;目标是带十万人玩转ChatGPT。 ChatGPT 是一个非常有用的工具&#xff0c;可以帮助你…

【C语言系列】深入理解指针(1)

前言 总所周知&#xff0c;C语言中指针部分是非常重要的&#xff0c;这一件我们会介绍指针相关的内容&#xff0c;当然后续我还会出大概4篇与指针相关的文章&#xff0c;来深入的讲解C语言指针部分&#xff0c;希望能够帮助到指针部分薄弱或者根本不会的程序员们&#xff0c;后…

深度学习 Pytorch 基本优化思想与最小二乘法

在正式开始进行神经网络建模之前&#xff0c;我们还需要掌握pytorch中最核心的基础数学工具——autograd(自动微分)模块。虽然对于任何一个通用的深度学习框架都会提供许多自动优化的算法和现成的loss function&#xff0c;但如果想更深入理解神经网络&#xff0c;对深度学习的…