Android基础控件——EditText的自定义、高仿iOS的UITextField

本文介绍如何自定义Android中EditText控件,实现类似iOS UITextField的功能,包括文本输入时显示清除图标的特性。通过监听文本变化及点击事件,完成输入框状态的切换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

EditText的自定义、高仿iOS的UITextField


学习,学习,学以致用,让基础控件贴近实战效果

EditText是常用的文本框输入控件,它没有像iOS的UITextField那样,只要一个属性就可以在输入的时候弹出一个清除所有文本的图标,那么我们就要自定义一个,废话不多说,Hensen老师开车啦

iOS的效果

这里写图片描述

要实现的效果(有点卡,耐心看)

这里写图片描述

1.1 实现分析

  1. 使用EditText的setCompoundDrawablesWithIntrinsicBounds()填充图标
  2. 使用EditText监听TextChangedListener
  3. 使用Rect监听图标的点击事件

1.2 实现代码

1、成员变量

//用户图标 20x20 具体分辨率根据不同机子适配
private Drawable imageUser;
//删除图标 15x15 具体分辨率根据不同机子适配
private Drawable imageGray;
private Context mContext;

2、构造方法

public MyEditText(Context context) {
    this(context, null);
}

public MyEditText(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    this.mContext = context;
    init(context);
}

3、初始化并监听文本变化

private void init(Context context) {
    imageUser = ContextCompat.getDrawable(context, R.drawable.user);
    imageGray = ContextCompat.getDrawable(context, R.drawable.gray);
    //初始化
    setImage();

    addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            setImage();
        }
    });
}

private void setImage() {
    //setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom)
    //左边图标放置用户图标,右边图标放置删除图标,即第一个参数和第三个参数
    if (length() > 0) {
        setCompoundDrawablesWithIntrinsicBounds(imageUser, null, imageGray, null);
    } else {
        setCompoundDrawablesWithIntrinsicBounds(imageUser, null, null, null);
    }
}

4、监听点击事件

public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_UP:
            //得到手指离开EditText时的X Y坐标
            int x = (int) event.getRawX();
            int y = (int) event.getRawY();
            //创建一个长方形
            Rect rect = new Rect();
            //让长方形的宽等于edittext的宽,让长方形的高等于edittext的高
            getGlobalVisibleRect(rect);
            //把长方形缩短至右边30dp,约等于(padding+图标分辨率)
            rect.left = rect.right - dip2px(mContext, 30);
            //如果x和y坐标在长方形当中,说明你点击了右边的xx图片,清空输入框
            if (rect.contains(x, y)) {
                setText("");
            }
            break;
        default:
            break;
    }
    return super.onTouchEvent(event);
}

public static int dip2px(Context context, float dpValue) {
    final float scale = context.getResources().getDisplayMetrics().density;
    return (int) (dpValue * scale);
}

1.3 布局实现

注意:

  1. 由于不同机子的分辨率不同,需要对EditText的drawablePadding和Padding做相应的处理
  2. 由于不同机子的分辨率不同,需要对图标的分辨率进行适配
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <com.handsome.boke2.EditText.MyEditText
        android:layout_width="200dp"
        android:layout_height="35dp"
        android:background="@drawable/bg_gray_border"
        android:drawablePadding="8dp"
        android:hint="请输入用户名"
        android:padding="8dp" />
</RelativeLayout>

而这个bg_gray_border其实就是个xml的背景图,代码如下

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#ffffff" />
    <stroke
        android:width="0.01dp"
        android:color="#DEDEDE" />
    <corners android:radius="6dp" />
</shape>

源码和图标下载

到这里的课程就结束,如果对基础控件感兴趣的朋友可以关注我博客的基础控件系列

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

许英俊潇洒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值