EditText左侧设置文字,右侧设置图片

自定义EditText实现左侧可以设置文字,右侧设置的图片可处理两个功能;1:清除当前输入框内容;2.隐藏或显示密码。可选择设置editText下方的下划线,默认有下划线

先看一下实现的效果

左侧文字的颜色、大小、左侧文字跟光标的间距都可以更改

1.在values包下创建attrs.xml文件

<declare-styleable name="AutoEditTextView">
        <!--//左侧设置的文字,如果设置了就显示,不设置就不显示-->
        <attr name="leftText" format="string" />
        <!--左侧文字的颜色-->
        <attr name="leftTextColor" format="color" />
        <!--左侧文字的大小-->
        <attr name="leftTextSize" format="float" />
        <!--左侧文字距离光标的距离-->
        <attr name="leftTextPadding" format="integer" />
        <!--右侧图标点击需要处理的类型 0 删除当前内容 1隐藏和显示密码-->
        <attr name="rightButtonClickType" format="integer" />
        <!--是否要显示底部的线-->
        <attr name="isShowDownLine" format="boolean" />
        <!--设置底部线默认的颜色-->
        <attr name="downLineDefaultColor" format="color"/>
        <!--设置EditText获取焦点之后底部线的颜色-->
        <attr name="downLineFocusColor" format="color"/>
</declare-styleable>

2.编写AutoEditTextView继承android.support.v7.widget.AppCompatEditText

package cn.wangxiao.home.education.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.text.method.HideReturnsTransformationMethod;
import android.text.method.PasswordTransformationMethod;
import android.util.AttributeSet;
import android.view.MotionEvent;

import cn.wangxiao.home.education.R;


/**
 * Created by ytt on 2018/7/19.
 * 定义一个左侧可以填写文字,右侧可以放置图片,点击右侧图片根据type实现功能
 * 还有下划线,下划线颜色根据获取焦点和未获取焦点有两种状态
 * 右侧图片功能
 * 1.删除当前输入文字,只有当前edittext有内容时才会显示该图片
 * 2.密码的显示和隐藏
 */
public class AutoEditTextView extends android.support.v7.widget.AppCompatEditText {
    //TODO 左侧的文字内容,没有则不设置
    private String leftText;
    //TODO 左侧文字的颜色
    private int leftTextColor;
    //TODO 左侧文字的大小
    private float leftTextSize;
    //TODO 左侧文字距离光标的距离
    private int leftTextPadding;
    //TODO 右侧图标点击的功能,0删除当前内容,1隐藏和显示密码
    private int clickType;
    //TODO 是否要显示底部的线
    private boolean isShowDownLine;
    //TODO 底部线显示的默认颜色
    private int downLineDefaultColor;
    //TODO 底部线现实的选中颜色
    private int downLineFocusColor;
    //绘制左侧文字的画笔
    private Paint mTextPaint;
    //绘制下方线的笔
    private Paint mLinePaint;
    private boolean isShowPass;

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

    public AutoEditTextView(Context context, AttributeSet attrs) {
        this(context, attrs,R.attr.editTextStyle);
    }

    public AutoEditTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initData(context, attrs, defStyleAttr);
    }

    private void initData(Context context, AttributeSet attrs, int defStyleAttr) {
        TypedArray typeArray = context.obtainStyledAttributes(attrs, R.styleable.AutoEditTextView, defStyleAttr, 0);
        leftText = typeArray.getString(R.styleable.AutoEditTextView_leftText);
        leftTextColor = typeArray.getColor(R.styleable.AutoEditTextView_leftTextColor, getColor(R.color.text3));
        leftTextSize = typeArray.getFloat(R.styleable.AutoEditTextView_leftTextSize, sp2px(16f));
        clickType = typeArray.getInt(R.styleable.AutoEditTextView_rightButtonClickType, 0);
        isShowDownLine = typeArray.getBoolean(R.styleable.AutoEditTextView_isShowDownLine, true);
        leftTextPadding = typeArray.getInt(R.styleable.AutoEditTextView_leftTextPadding, dip2px(8));
        downLineDefaultColor = typeArray.getColor(R.styleable.AutoEditTextView_downLineDefaultColor, getColor(R.color.grayLine));
        downLineFocusColor = typeArray.getColor(R.styleable.AutoEditTextView_downLineFocusColor, getColor(R.color.selectLine));
        typeArray.recycle();
        setBackground(null);
        initPaint();
    }


    private void initPaint() {
        mTextPaint = new Paint();
        mTextPaint.setColor(leftTextColor);
        mTextPaint.setTextSize(leftTextSize);
        mTextPaint.setAntiAlias(true);

        mLinePaint = new Paint();
        mLinePaint.setColor(downLineDefaultColor);
        mLinePaint.setAntiAlias(true);
        mLinePaint.setStrokeWidth(dip2px(1));

        //TODO 如果需要设置左侧的问题,需要重新计算padding
        if (!TextUtils.isEmpty(leftText)) {
            int paddingLeft = (int) mTextPaint.measureText(leftText) + getPaddingLeft() + leftTextPadding;
            //设置距离光标距离左侧的距离
            setPadding(paddingLeft, getPaddingTop(), getPaddingRight(), getPaddingBottom());
        }
    }


    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect);
        if (isShowDownLine) {
            mLinePaint.setColor(focused ? downLineFocusColor : downLineDefaultColor);
            invalidate();
        }
    }

    /**
     * getScrollX()这个方法是当editText只显示一行时,如果起始点设置成0会被挤出屏幕,
     * 看了一下TextView和View的源码才分析出来的
     * */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //TODO 绘制左侧的文字,并居中显示
        if (!TextUtils.isEmpty(leftText)) {
            canvas.drawText(leftText, getScrollX(), (getMeasuredHeight() - mTextPaint.getTextSize()) / 2 + mTextPaint.getTextSize(), mTextPaint);
        }
        //绘制底部的线
        if (isShowDownLine) {
            canvas.drawLine(getScrollX(), this.getHeight() - dip2px(1), getScrollX() + this.getWidth(), this.getHeight() - dip2px(1), mLinePaint);
        }
    }

    /* @说明:isInnerWidth, isInnerHeight为ture,触摸点在删除图标之内,则视为点击了删除图标
     * event.getX() 获取相对应自身左上角的X坐标
     * event.getY() 获取相对应自身左上角的Y坐标
     * getWidth() 获取控件的宽度
     * getHeight() 获取控件的高度
     * getTotalPaddingRight() 获取删除图标左边缘到控件右边缘的距离
     * getPaddingRight() 获取删除图标右边缘到控件右边缘的距离
     * isInnerWidth:
     *  getWidth() - getTotalPaddingRight() 计算删除图标左边缘到控件左边缘的距离
     *  getWidth() - getPaddingRight() 计算删除图标右边缘到控件左边缘的距离
     * isInnerHeight:
     *  distance 删除图标顶部边缘到控件顶部边缘的距离
     *  distance + height 删除图标底部边缘到控件顶部边缘的距离
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            if (getCompoundDrawables()[2] != null) {
                int x = (int) event.getX();
                int y = (int) event.getY();
                Rect rect = getCompoundDrawables()[2].getBounds();
                int height = rect.height();
                int distance = (getHeight() - height) / 2;
                boolean isInnerWidth = x > (getWidth() - getTotalPaddingRight()) && x < (getWidth() - getPaddingRight());
                boolean isInnerHeight = y > distance && y < (distance + height);
                if (isInnerWidth && isInnerHeight) {
                    dealRightButtonClickType();
                }
            }
        }
        return super.onTouchEvent(event);
    }

    //TODO 处理右侧图标点击事件
    private void dealRightButtonClickType() {
        if (clickType == 0) {//删除当前内容
            setText("");
        } else if (clickType == 1) {//隐藏和显示密码
            isShowPass = !isShowPass;
            setTransformationMethod(isShowPass ? HideReturnsTransformationMethod.getInstance() : PasswordTransformationMethod.getInstance());
            setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1],
                    isShowPass ? getDrawable(R.mipmap.input_hidden_text) : getDrawable(R.mipmap.input_show_text), getCompoundDrawables()[3]);
        }
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
        super.setText(text, type);
        if (!TextUtils.isEmpty(text)) {
            setSelection(text.toString().length() - 1);
        }
    }

    public Drawable getDrawable(int id) {
        Drawable drawable = getContext().getResources().getDrawable(id);
        drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
        return drawable;
    }

    //dip--->px   1dp = 1px   1dp = 2px
    public int dip2px(double dip) {
        //dp和px的转换关系比例值
        float density = getContext().getResources().getDisplayMetrics().density;
        return (int) (dip * density + 0.5);
    }

    public int sp2px(float spValue) {
        final float fontScale = getResources().getDisplayMetrics().scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }

    public int getColor(int id) {
        return ContextCompat.getColor(getContext(), id);
    }
}

隐藏和显示密码的图标需要自己更改成自己的图片名称哦~不需要该功能也可以去掉

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值