Edittext自定义实现居中 右侧删除的逻辑

在实际开发中,产品有这样子那样子的需求,尤其UI给你找困难
下面是做到的效果
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
界面的一些逻辑就不写了
主要写下 我封装的这个控件

package com.jingyun.wallet.ui.view;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.animation.Animation;
import android.view.animation.CycleInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.EditText;

import com.jingyun.listener.SoftKeyBoardListener;
import com.jingyun.wallet.R;

import androidx.annotation.RequiresApi;

/**
 * @author dkjuan
 */
@SuppressLint("AppCompatCustomView")
public class CenterEdittext extends EditText {

	private Context context;
	private int drawableIcon;
	// icon图标
	private boolean isShowCenter;
	//是否居中显示icon,默认为不居中
	private boolean isShowLeft, isShowRight;
	//键盘打开后icon是否显示在左边,默认为不显示icon
	private boolean isShowHint;
	//键盘打开后是否显示提示文字,默认为显示
	private boolean isOpen;
	//是否开启使用,默认为false
	private boolean isDraw = true;
	//是否绘制,配合居中显示使用
	private String hintText;
	/**
	 * 删除按钮的引用
	 */
	private Drawable mClearDrawable;

	public CenterEdittext(Context context) {
		super(context);
		this.context = context;
		initView(null);
	}

	public CenterEdittext(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.context = context;
		initView(attrs);
	}

	public CenterEdittext(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		this.context = context;
		initView(attrs);
	}

	@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
	public CenterEdittext(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
		super(context, attrs, defStyleAttr, defStyleRes);
		this.context = context;
		initView(attrs);
	}

	private void initView(AttributeSet attrs) {
		if (attrs != null) {
			TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CenterEdittext);
			isShowCenter = array.getBoolean(R.styleable.CenterEdittext_isCenter, false);
			isShowLeft = array.getBoolean(R.styleable.CenterEdittext_isShowLeft, false);
			isShowRight = array.getBoolean(R.styleable.CenterEdittext_isShowRight, true);
			isShowHint = array.getBoolean(R.styleable.CenterEdittext_isShowHint, true);
			isOpen = array.getBoolean(R.styleable.CenterEdittext_isOpen, true);
			drawableIcon = array.getResourceId(R.styleable.CenterEdittext_drawableIcon, R.mipmap.icon_search);
			//获取EditText的DrawableRight,假如没有设置我们就使用默认的图片
			mClearDrawable = getCompoundDrawables()[2];
			if (mClearDrawable == null) {
				mClearDrawable = getResources().getDrawable(R.mipmap.icon_fork_close);
			}
			array.recycle();
		}
		if (context instanceof Activity && isOpen) {
			hintText = getHint().toString();
			SoftKeyBoardListener.setListener((Activity) context, new SoftKeyBoardListener.OnSoftKeyBoardChangeListener() {
				@Override
				public void keyBoardShow(int height) {
					//键盘处于打开状态
					setCursorVisible(true);
					// 显示光标
					isDraw = false;
					//重新绘制(icon居左或者不显示)
					if (!isShowHint) {
						setHint("");
					} else {
						if (!TextUtils.isEmpty(hintText)) {
							setHint(hintText);
						}

					}
				}

				@Override
				public void keyBoardHide(int height) {
					//键盘处于关闭状态
					setCursorVisible(false);
					// 隐藏光标
					isDraw = TextUtils.isEmpty(getText().toString());
					if (!TextUtils.isEmpty(hintText)) {
						setHint(hintText);
					}

				}
			});
		}
	}

	@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
	@Override
	protected void onDraw(Canvas canvas) {
		if (!isOpen) {
			super.onDraw(canvas);
			return;
		}
		if (isShowCenter && isDraw) {
			// 将icon绘制在中间
			setCompoundDrawablesWithIntrinsicBounds(context.getResources().getDrawable(drawableIcon), null, null, null);
			//绘制图片
			float textWidth = getPaint().measureText(getHint().toString());
			//得到文字宽度
			int drawablePadding = getCompoundDrawablePadding();
			//得到drawablePadding宽度
			int drawableWidth = context.getResources().getDrawable(drawableIcon).getIntrinsicWidth();
			//得到图片宽度
			float bodyWidth = textWidth + drawableWidth + drawablePadding;
			//计算距离
			canvas.translate((getWidth() - bodyWidth - getPaddingLeft() - getPaddingRight()) / 2, 0);
			//最终绘制位置
			super.onDraw(canvas);
			setClearIconVisible(false);
		} else {
			if (isShowLeft) {
				setCompoundDrawablesWithIntrinsicBounds(context.getResources().getDrawable(drawableIcon), null, null, null);
			} else {
				setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
			}
			if (!TextUtils.isEmpty(this.getText().toString())) {
				setClearIconVisible(true);
			} else {
				setClearIconVisible(false);
			}
			super.onDraw(canvas);
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {

		if (mClearDrawable != null && event.getAction() == MotionEvent.ACTION_UP) {
			int x = (int) event.getX();
			//判断触摸点是否在水平范围内
			boolean isInnerWidth = (x > (getWidth() - getTotalPaddingRight())) &&
					(x < (getWidth() - getPaddingRight()));
			//获取删除图标的边界,返回一个Rect对象
			Rect rect = mClearDrawable.getBounds();
			//获取删除图标的高度
			int height = rect.height();
			int y = (int) event.getY();
			//计算图标底部到控件底部的距离
			int distance = (getHeight() - height) / 2;
			//判断触摸点是否在竖直范围内(可能会有点误差)
			//触摸点的纵坐标在distance到(distance+图标自身的高度)之内,则视为点中删除图标
			boolean isInnerHeight = (y > distance) && (y < (distance + height));
			if (isInnerHeight && isInnerWidth) {
				this.setText("");
			}
		}
		return super.onTouchEvent(event);
	}

	/**
	 * 设置清除图标的显示与隐藏,调用setCompoundDrawables为EditText绘制上去
	 *
	 * @param visible
	 */
	private void setClearIconVisible(boolean visible) {
		if (isShowRight) {
			Drawable right = visible ? mClearDrawable : null;
			setCompoundDrawablesWithIntrinsicBounds(getCompoundDrawables()[0], getCompoundDrawables()[1],
					right, getCompoundDrawables()[3]);
		}

	}
	/**
	 * 设置晃动动画
	 */
	public void setShakeAnimation() {
		this.setAnimation(shakeAnimation(5));
	}

	/**
	 * 晃动动画
	 *
	 * @param counts 1秒钟晃动多少下
	 * @return
	 */
	public static Animation shakeAnimation(int counts) {
		Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);
		translateAnimation.setInterpolator(new CycleInterpolator(counts));
		translateAnimation.setDuration(1000);
		return translateAnimation;
	}
}
 <com.jingyun.wallet.ui.view.CenterEdittext
                    android:id="@+id/etSearchContact"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/dp_40"
                    android:layout_marginLeft="@dimen/dp_16"
                    android:layout_marginRight="@dimen/dp_16"
                    android:background="@drawable/bg_code_edit"
                    android:drawablePadding="@dimen/dp_3"
                    android:hint="@string/addcontact_search"
                    android:paddingLeft="@dimen/dp_10"
                    android:paddingRight="@dimen/dp_10"
                    android:textSize="@dimen/sp_14"
                    android:imeOptions="actionSearch"
                    android:digits="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
                    android:singleLine="true"
                    android:inputType="text"
                    binding:isCenter="true"
                    android:text="@={viewModel.serachText}"
                    binding:isOpen="true"
                    binding:isShowHint="true"
                    binding:isShowLeft="false"
                    binding:isShowRight="true"/>

重要的还有属性

 <!--自定义edittext搜索-->
    <declare-styleable name="CenterEdittext">
        <attr name="isCenter" format="boolean" />
        <attr name="isShowLeft" format="boolean" />
        <attr name="isShowRight" format="boolean" />
        <attr name="isShowHint" format="boolean" />
        <attr name="drawableIcon" format="reference" />
        <attr name="isOpen" format="boolean" />
    </declare-styleable>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值