自定义MaterialEditText

news2024/7/4 23:55:32

自定义MaterialEditText

日记

现在都不流行写博客了,因为这玩意都认为对于面试没啥用,我感觉很多事情不应该太功利。所谓博客还是更多的应该用来进行自己日常学习的归纳和总结,而不是去贪图所谓的面试加分。因为面试可能是一时的,但是自己实际是否掌握了,那就是长久的。

今天晚上就更新啦,哈哈哈哈,期待期待。

前言

一如既往,这是我日常学习的日记,最近在巩固一些基础东西,总感觉一些Android基础还是偏薄弱。所以还是打算从基础重新来一遍,真的,很多时候,很多问题出现的原因并不是顶层的原因,而是我们从根本,从基础上就不牢靠。最近闲下来就在看扔物线的视频,说真的,很多其实挺基础的,但是感觉能在基础上面翻出花样来其实也是一种本事。因此,来讲讲今天的主题自定义MaterialEditText。

当然,我并不打算完整地实现一摸一样的一个相同库出来,如果是那样,那就完蛋了。今天就选一个最简单的案例来讲讲吧。就当是前面几讲的归纳和总结了。

正文

我们需要实现的目标效果如下:没有输入文字的时候EditText显示的是Hint的提示信息,当输入文字之后,EditText显示的是实际输入的文字信息,同时Label从下到上,从浅变深显示Label。
请添加图片描述

来整体规划一下思路,我们只需要重点关注上面Label的显示状态的变化即可,Label的变化说到底仅仅是一个属性动画。我们需要在Draw的时候,根据动画进度,来动态地进行绘制即可。

首先,我们先绘制输入完成后地文本样式:总体就是上下结构,上面是一行文本,下面是可输入的文本框。这个很简单,首先,在视图定义的时候设置视图高度为wrap_content,然后在视图初始化的时候修改视图的padding从而给hint提示文本让出对应的空间即可。

//Hint栏距离顶端距离,单纯为了美观
val MARGIN_TOP = 20.dp    
init {
    //设置初始间距
    setPadding(
        paddingLeft,
        //给hint文本绘制空出对应的位置
        (paddingTop + MARGIN_TOP + textSize).toInt(),
        paddingRight,
        paddingBottom
    )
    paint.textSize = textSize
}

位置空好了,我们来绘制对应的Hint文本。因为是Demo,我们就设计的简单一点,不专门给hint设置什么特别的文字样式了,除了文字大之外的其他值就直接使用默认值就行了。

private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)
    canvas.drawText(
        hint.toString(),
        paddingLeft.toFloat(),
        textSize + MARGIN_TOP,
        paint
    )
}

接下来,我们就要在文字长度产生变化的时候触发对于Hint文字的动画。重点关注onTextChangedonDraw这两个方法。整体思路是在onTextChanged方法回调中判断文字变化前的长度和文字变化后的长度。

  1. 文字从无变有,hint标题栏逐渐上浮,透明度从全透明到纯色
  2. 文字从有变无,hint标题栏逐渐下沉,透明度从纯色到全透明

我们在自定义MaterialEditText中定义一个局部变量fraction来作为属性动画的操作对象,在onDraw方法中根据fraction局部变量来动态的控制Hint标题栏的透明度和动态位置。

来看看具体的实现吧。

/**
 * 自定义EditText
 */
//Hint栏距离顶端距离
val MARGIN_TOP = 20.dp

class MaterialEditText(context: Context, attributeSet: AttributeSet) :
    AppCompatEditText(context, attributeSet) {
    //动画执行进度
    var fraction = 1f
        set(value) {
            field = value
            invalidate()
        }
    var supportLabel = false
    private val offsetAnimator: ObjectAnimator by lazy {
        ObjectAnimator.ofFloat(this, "fraction", 0f, 1f).apply { duration = 1000 }
    }
    private val paint = Paint(Paint.ANTI_ALIAS_FLAG)

    init {
        val materialEditTextAttrs =
            context.obtainStyledAttributes(attributeSet, R.styleable.MaterialEditText)
        supportLabel =
            materialEditTextAttrs.getBoolean(R.styleable.MaterialEditText_support_label, false)
        materialEditTextAttrs.recycle()
        if (supportLabel) {
            //设置初始间距
            setPadding(
                paddingLeft,
                (paddingTop + MARGIN_TOP + textSize).toInt(),
                paddingRight,
                paddingBottom
            )
            paint.textSize = textSize
        }
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        if(!supportLabel)return
        paint.alpha = ((1 - fraction) * 255).toInt()
        canvas.drawText(
            hint.toString(),
            paddingLeft.toFloat(),
            textSize + MARGIN_TOP + textSize * fraction,
            paint
        )
    }

    override fun onTextChanged(
        text: CharSequence?,
        start: Int,
        lengthBefore: Int,
        lengthAfter: Int
    ) {
        super.onTextChanged(text, start, lengthBefore, lengthAfter)
        if(!supportLabel) return
        if (text.isNullOrEmpty() && lengthBefore > 0) {
            offsetAnimator.start()
        } else if (lengthBefore <= 0 && lengthAfter > 0) {
            offsetAnimator.reverse()
        }
    }

}


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

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

相关文章

Apple Vision Pro的价格并没有看起来那么疯狂

When Apple announced the price of their groundbreaking new mixed reality headset, the Vision Pro, jaws around the world collectively dropped. At a hefty $3,499, it’s not for everyone, but is it really so unreasonable if we take a closer look? 当苹果宣布其…

CSS特性、背景属性和显示模式

CSS特性 CSS特性&#xff1a;化简代码 / 定位问题&#xff0c;并解决问题 继承性层叠性优先级 继承性 继承性&#xff1a;子级默认继承父级的文字控制属性。 注意&#xff1a;如果标签有默认文字样式会继承失败。 例如&#xff1a;a 标签的颜色、标题的字体大小。 层叠性 …

前端 sentry 接入钉钉机器人

sentry 接入钉钉机器人 打开钉钉,添加机器人 此时会得到Webhook地址,记录一下,以后会用到 sentry 端设置 看看这里有木有钉钉插件,有的话开启插件,并配置这里我说一下没有的情况下,我们何如设置 这里需要填写webhook url 这个的url 需要是一个公网的地址,不可以是本地…

HID协议学习

HID协议学习 0. 文档资料 USB_HID协议中文版_USB接口HID设备_AUJsRmB9kg.pdf HID报告描述符精细说明_mgCxM8_ci9.pdf hut1_22_U3cvnwn_ZZ.pdf 1. 基本概念 HID协议是一种基于USB的通讯协议&#xff0c;用于在计算机和输入设备之间进行数据传输。HID协议定义了标准的数据格…

动态规划算法(子数组专题1)

动态规划算法专辑之子数组问题&#xff08;1&#xff09; 本专栏将从状态定义、状态转移方程、初始化、填表顺序、返回值这五大细节来详细讲述动态规划的算法的解题思路及代码实现一、什么是子数组 子数组&#xff1a;子数组是数组中的一个连续部分的集合&#xff0c;子序列可…

Python+Selenium UI自动化测试环境搭建及使用

目录 一、什么是Selenium &#xff1f; 二、Selenium环境搭建 三、WebDriver API 总结&#xff1a; 一、什么是Selenium &#xff1f; Selenium 是一个浏览器自动化测试框架&#xff0c;它主要用于web应用程序的自动化测试&#xff0c;其主要特点如下&#xff1a;开源、免费…

缅怀(上次写博客是2009年10月24日)

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

Nucleo-F411RE (STM32F411)LL库体验 3 - 滴嗒定时器的配置

Nucleo-F411RE &#xff08;STM32F411&#xff09;LL库体验 3 - 滴嗒定时器的配置 1、LL库延时 LL库初始化时钟的时候调用了LL_Init1msTick(100000000)函数&#xff0c;这个函数其实就是初始化了系统的滴答定时器。 LL_InitTick原型如下&#xff1a; load值 sysclk/1000&a…

RocketMQ架构和工作流程

一.MQ概述 1.简介 MQ&#xff0c;Message Queue&#xff0c;是一种提供消息队列服务的中间件&#xff0c;也称为消息中间件&#xff0c;是一套提供了消息生产、存储、消费全过程API的软件系统。消息即数据。一般消息的体量不会很大。 2.用途 限流削峰 MQ可以将系统的超量请求…

接口测试工具怎么选?这个技巧你一定要知道

目录 前言 一、易用性 二、灵活性 三、可靠性 测试用例 接口测试数据 自动化测试 测试报告 总结 前言 当今软性开发中&#xff0c;接口测试已成为必不可少的一环&#xff0c;该如何选择接口测试工具?选择合适的接口测试工具对于程房员来说非常重要&#xff0c;因为…

SQL死锁

前言&#xff1a; 使用脚本刷数据时&#xff0c;开多线程经常遇到死锁现象&#xff0c;面试也经常问到&#xff0c;故开此篇 日志错误示例&#xff1a; ### Error updating database. Cause: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock fo…

Tplink企业版开启ipv6

Tplink企业版开启ipv6 1、登录路由器 路由器的默认地址一般为&#xff1a;192.168.0.1&#xff0c;登录成功后如下图&#xff1a; 2、WAN设置ipv6 wan是设置启用ipv6模式&#xff0c;如果这里无法启用&#xff0c;主要是因为“接口模式”中启用了桥接模式&#xff0c;可以关闭…

多线程详解

多线程详解 Process和Thread 程序是指令和数据的有序结合&#xff0c;其本身没有任何运行的含义&#xff0c;是一个静态的概念 进程是执行程序的一次执行过程&#xff0c;是一个动态的概念&#xff0c;是系统资源分配的单位 通常在一个进程中可以包含若干个线程。线程是CPU调…

(数组) 922. 按奇偶排序数组 II ——【Leetcode每日一题】

❓922. 按奇偶排序数组 II 难度&#xff1a;简单 给定一个非负整数数组 nums&#xff0c; nums 中一半整数是 奇数 &#xff0c;一半整数是 偶数 。 对数组进行排序&#xff0c;以便当 nums[i] 为奇数时&#xff0c;i 也是 奇数 &#xff1b;当 nums[i] 为偶数时&#xff0c…

开发语言的更新换代,都是为了更好地提高生产力,Kotlin也是如此~

作为一名Android开发&#xff0c;学习Kotlin是很有必要的。以下是一些原因&#xff1a; 1.Kotlin是官方支持的语言。 在2017年Google宣布支持Kotlin作为官方开发语言后&#xff0c;Kotlin已成为Android生态系统的重要组成部分。此举表明Kotlin的发展前景非常广阔&#xff0c;…

uniapp兼容多pda扫描扫码

前景 网上有现成的针对单个pda扫码录入的代码&#xff0c;但是公司的需求是在多个不同厂商pda上运行&#xff0c;这就会导致不同的pda默认的广播动作和广播标签不一致的情况&#xff0c;目前也没有获取这俩字段的api。 单个pda扫描扫码代码 先创建一个scanCode.js的文件 le…

UnoCSS给了我一个不用tailwindcss的理由

相同的原由 & 前言 如果你没有听说过 tailwindcss 或者 unocss&#xff0c;请先 return 先去了解一下&#x1f61d;。 开发上&#xff1a;可能为你甚至你们的前端团队节省很多写样式的时间&#xff0c;也能让你或者你们的项目开发体验有很大提升生产上&#xff1a;你们的…

VS2013创建一个MFC工程的步骤

目录 1、新建项目&#xff0c;选择”MFC应用程序“&#xff1b; 2、应用程序类型&#xff0c;选择“基于对话框”&#xff1b; 3、对话框的标题&#xff0c;默认是和项目的名字一致&#xff0c;按需修改&#xff1b; 4、高级功能&#xff0c;可以保持默认&#xff1b; 5、…

一个女测试工程师的大厂日常

今天给大家分享两个朋友的故事&#xff0c;他们分别在国内两家顶尖的互联网大厂&#xff0c;一个在头条&#xff0c;一个在蚂蚁。 头条的故事 头条的主人公&#xff0c;在入职后的一年里&#xff0c;晚上十点半下班是比较早了&#xff0c;基本上都是十一点半左右下班&#xff…

低成本开发专属小程序支持自定义开发设计

传统定制开发小程序成本高&#xff0c;还需要不断地沟通和交流才能一步步地去实现你想要的功能和效果&#xff0c;那么除了传统的定制开发小程序外&#xff0c;用户其实还可以选择使用模板开发小程序&#xff0c;不仅能实现小程序的所有基础功能&#xff0c;还不用编程维护和开…