Android EditText实现分割输入内容

在项目中可能会有许多需要输入手机号码、银行卡号或者身份证号等内容的输入框。如果直接输入的话将会是一堆号码堆在一起,第一是不太美观,第二也容易出错,用户体验不太好。但是若将输入的号码按特定格式进行分割将会大大提高用户体验!

以下是对常用的号码进行简单封装的自定义输入框控件,方便我们在开发过程中使用:

  • 该控件支持xml属性指定,也支持代码指定;
  • 该控件支持类型分别为电话号码(000 0000 0000)、银行卡号(0000 0000 0000 0000 000)和身份证号(000000 0000 0000 0000)。

效果图

自定义EditText

/**
 * @Description 分割输入框
 * @Author 一花一世界
 */
public class ContentWithSpaceEditText extends EditText {

  public static final int TYPE_PHONE = 0;
  public static final int TYPE_CARD = 1;
  public static final int TYPE_IDCARD = 2;
  private int maxLength = 100;
  private int contentType;
  private int start, count, before;
  private String digits;

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

  public ContentWithSpaceEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
    parseAttributeSet(context, attrs);
  }

  public ContentWithSpaceEditText(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    parseAttributeSet(context, attrs);
  }

  private void parseAttributeSet(Context context, AttributeSet attrs) {
    TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ContentWithSpaceEditText, 0, 0);
    contentType = ta.getInt(R.styleable.ContentWithSpaceEditText_type, 0);
    ta.recycle();
    initType();
    setSingleLine();
    addTextChangedListener(watcher);
  }

  private void initType() {
    if (contentType == TYPE_PHONE) {
      maxLength = 13;
      digits = "0123456789 ";
      setInputType(InputType.TYPE_CLASS_NUMBER);
    } else if (contentType == TYPE_CARD) {
      maxLength = 23;
      digits = "0123456789 ";
      setInputType(InputType.TYPE_CLASS_NUMBER);
    } else if (contentType == TYPE_IDCARD) {
      maxLength = 21;
      digits = "0123456789xX ";
      setInputType(InputType.TYPE_CLASS_TEXT);
    }
    setFilters(new InputFilter[]{new InputFilter.LengthFilter(maxLength)});
  }

  @Override
  public void setInputType(int type) {
    super.setInputType(type);
    // setKeyListener要在setInputType后面调用,否则无效
    if (!TextUtils.isEmpty(digits)) {
      setKeyListener(DigitsKeyListener.getInstance(digits));
    }
  }

  private TextWatcher watcher = 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) {
      ContentWithSpaceEditText.this.start = start;
      ContentWithSpaceEditText.this.before = before;
      ContentWithSpaceEditText.this.count = count;
    }

    @Override
    public void afterTextChanged(Editable s) {
      if (s == null) {
        return;
      }
      //判断是否是在中间输入,需要重新计算
      boolean isMiddle = (start + count) < (s.length());
      //在末尾输入时,是否需要加入空格
      boolean isNeedSpace = false;
      if (!isMiddle && isSpace(s.length())) {
        isNeedSpace = true;
      }
      if (isMiddle || isNeedSpace || count > 1) {
        String newStr = s.toString();
        newStr = newStr.replace(" ", "");
        StringBuilder sb = new StringBuilder();
        int spaceCount = 0;
        for (int i = 0; i < newStr.length(); i++) {
          sb.append(newStr.substring(i, i + 1));
          //如果当前输入的字符下一位为空格(i+1+1+spaceCount),因为i是从0开始计算的,所以一开始的时候需要先加1
          if (isSpace(i + 2 + spaceCount)) {
            sb.append(" ");
            spaceCount += 1;
          }
        }
        removeTextChangedListener(watcher);
        s.replace(0, s.length(), sb);
        //如果是在末尾的话,或者加入的字符个数大于零的话(输入或者粘贴)
        if (!isMiddle || count > 1) {
          setSelection(s.length() <= maxLength ? s.length() : maxLength);
        } else if (isMiddle) {
          //如果是删除
          if (count == 0) {
            //如果删除时,光标停留在空格的前面,光标则要往前移一位
            if (isSpace(start - before + 1)) {
              setSelection((start - before) > 0 ? start - before : 0);
            } else {
              setSelection((start - before + 1) > s.length() ? s.length() : (start - before + 1));
            }
          }
          //如果是增加
          else {
            if (isSpace(start - before + count)) {
              setSelection((start + count - before + 1) < s.length() ? (start + count - before + 1) : s.length());
            } else {
              setSelection(start + count - before);
            }
          }
        }
        addTextChangedListener(watcher);
      }
    }
  };

  private boolean isSpace(int length) {
    if (contentType == TYPE_PHONE) {
      return isSpacePhone(length);
    } else if (contentType == TYPE_CARD) {
      return isSpaceCard(length);
    } else if (contentType == TYPE_IDCARD) {
      return isSpaceIDCard(length);
    }
    return false;
  }

  private boolean isSpacePhone(int length) {
    return length >= 4 && (length == 4 || (length + 1) % 5 == 0);
  }

  private boolean isSpaceCard(int length) {
    return length % 5 == 0;
  }

  private boolean isSpaceIDCard(int length) {
    return length > 6 && (length == 7 || (length - 2) % 5 == 0);
  }

  public void setContentType(int contentType) {
    this.contentType = contentType;
    initType();
  }

  public String getTextWithoutSpace() {
    return super.getText().toString().replace(" ", "");
  }

  /**
   * @Description 内容校验
   */
  public boolean isContentCheck() {
    String text = getTextWithoutSpace();
    if (contentType == TYPE_PHONE) {
      if (TextUtils.isEmpty(text)) {
        ToastUtil.showText(UIUtils.getString(R.string.phone_number_not_empty));
      } else if (text.length() < 11) {
        ToastUtil.showText(UIUtils.getString(R.string.phone_number_incorrect_length));
      } else {
        return true;
      }
    } else if (contentType == TYPE_CARD) {
      if (TextUtils.isEmpty(text)) {
        ToastUtil.showText(UIUtils.getString(R.string.bank_card_not_empty));
      } else if (text.length() < 16) {
        ToastUtil.showText(UIUtils.getString(R.string.bank_card_incorrect_length));
      } else {
        return true;
      }
    } else if (contentType == TYPE_IDCARD) {
      if (TextUtils.isEmpty(text)) {
        ToastUtil.showText(UIUtils.getString(R.string.identity_number_not_empty));
      } else if (text.length() < 18) {
        ToastUtil.showText(UIUtils.getString(R.string.identity_number_incorrect_length));
      } else {
        return true;
      }
    }
    return false;
  }
}

配置attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="ContentWithSpaceEditText">
    <attr name="type" format="enum">
      <enum name="phone" value="0" />
      <enum name="card" value="1" />
      <enum name="IDCard" value="2" />
    </attr>
  </declare-styleable>
</resources>

布局文件中使用

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="@color/theme_bg"
  android:orientation="vertical">

  <com.wiggins.splitinput.widget.TitleView
    android:id="@+id/titleView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="@dimen/item_normal"
    android:layout_margin="@dimen/margin_normal"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <TextView
      android:layout_width="@dimen/btn_width_normal"
      android:layout_height="match_parent"
      android:gravity="center_vertical"
      android:text="@string/phone_number"
      android:textColor="@color/blue"
      android:textSize="@dimen/font_normal" />

    <com.wiggins.splitinput.widget.ContentWithSpaceEditText
      android:id="@+id/edt_phone_input"
      android:layout_width="match_parent"
      android:layout_height="@dimen/item_normal"
      android:background="@color/white"
      android:gravity="center"
      android:hint="@string/please_enter_content"
      android:inputType="number"
      android:textColor="@color/blue"
      android:textColorHint="@color/gray"
      android:textCursorDrawable="@null"
      android:textSize="@dimen/font_normal"
      app:type="phone" />
  </LinearLayout>

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="@dimen/item_normal"
    android:layout_margin="@dimen/margin_normal"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <TextView
      android:layout_width="@dimen/btn_width_normal"
      android:layout_height="match_parent"
      android:gravity="center_vertical"
      android:text="@string/bank_card_number"
      android:textColor="@color/blue"
      android:textSize="@dimen/font_normal" />

    <com.wiggins.splitinput.widget.ContentWithSpaceEditText
      android:id="@+id/edt_bank_card_input"
      android:layout_width="match_parent"
      android:layout_height="@dimen/item_normal"
      android:background="@color/white"
      android:gravity="center"
      android:hint="@string/please_enter_content"
      android:inputType="number"
      android:textColor="@color/blue"
      android:textColorHint="@color/gray"
      android:textCursorDrawable="@null"
      android:textSize="@dimen/font_normal"
      app:type="card" />
  </LinearLayout>

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="@dimen/item_normal"
    android:layout_margin="@dimen/margin_normal"
    android:gravity="center_vertical"
    android:orientation="horizontal">

    <TextView
      android:layout_width="@dimen/btn_width_normal"
      android:layout_height="match_parent"
      android:gravity="center_vertical"
      android:text="@string/identity_number"
      android:textColor="@color/blue"
      android:textSize="@dimen/font_normal" />

    <com.wiggins.splitinput.widget.ContentWithSpaceEditText
      android:id="@+id/edt_identity_input"
      android:layout_width="match_parent"
      android:layout_height="@dimen/item_normal"
      android:background="@color/white"
      android:gravity="center"
      android:hint="@string/please_enter_content"
      android:inputType="number"
      android:textColor="@color/blue"
      android:textColorHint="@color/gray"
      android:textCursorDrawable="@null"
      android:textSize="@dimen/font_normal"
      app:type="IDCard" />
  </LinearLayout>
</LinearLayout>

项目地址:传送门

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android实现自定义带删除功能的EditText实例

    1.说明 自定义带删除功能的EditText有两种方法,第一种是用组合视图的方法,即在一个view视图里面左侧放置一个EditText,右侧放置一个ImageView,但是这样增加了视图的层次,而且对输入内容的长度要做一定的处理. 第二种是重新定义EditText组件,增加相应的事件处理,即可达到很好的效果,效果图如下: 2.ClearEditText的JAVA类文件 /** * @说明: 自定义带删除按钮的EditText * */ public class ClearEditText ext

  • Android EditText限制输入字符的方法总结

     Android EditText限制输入字符的方法总结 最近项目要求限制密码输入的字符类型, 例如不能输入中文.   现在总结一下EditText的各种实现方式,  以比较各种方法的优劣.  第一种方式:  设置EditText的inputType属性,可以通过xml或者Java文件来设置.假如我要设置为显示密码的形式,可以像下面这样设置: 在xml中,   Android:inputType="textPassword" 在java文件中,可以用 ev.setInputType(I

  • Android编程实现实时监听EditText文本输入的方法

    本文实例讲述了Android编程实现实时监听EditText文本输入的方法.分享给大家供大家参考,具体如下: 平时在做Android开发过程中经常要用到EditText,有时候可能需要监听你在TextView中输入的字数的状态和变化,以便于我们能做相应的提示和操作.我们可以通过下面的方式来实现. class EditChangedListener implements TextWatcher { private CharSequence temp;//监听前的文本 private int edi

  • Android 设置Edittext获取焦点并弹出软键盘

    Android 设置Edittext获取焦点并弹出软键盘 /** * EditText获取焦点并显示软键盘 */ public static void showSoftInputFromWindow(Activity activity, EditText editText) { editText.setFocusable(true); editText.setFocusableInTouchMode(true); editText.requestFocus(); activity.getWind

  • Android中自定义的dialog中的EditText无法弹出输入法解决方案

    1.解决无法弹出输入法: 在show()方法调用之前,用dialog.setView(new EditText(context))添加一个空的EditText,由于是自定义的AlertDialog,有我们指定的布局,所以设置这个不会影响我们的功能,这样就可以弹出输入法了-- 2.可以弹出输入法了,但了为了增强用户体验性,当dialog中含有editText时应该,在显示dialog的同时自动弹出键盘: (1) 可以在自定义的dialog中增加如下方法: public void showKeybo

  • Android中搜索图标和文字居中的EditText实例

    效果图: 需要自定义view,具体实现如下: import android.widget.EditText; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.drawable.Drawable; import android.uti

  • Android之EditText控制禁止输入空格和回车

    1.EdiTtext输入框控制不能输入空格,给EditText添加一个addTextChangedListener监听,如果有空格split截取截取再for循环将截取后不包含空格的字符串数组重新排列这样这个字符串就不包含空格了,最后将这个字符串重新写入EditText,这时会出现一个问题就是光标会自动跳转到第一个位置,在onTextChanged中会有一个叫做start的变量他会传入在这个空格输入之前的光标位置,EditText.setSelection(int)来改变光标的位置具体位置. 具体

  • Android EditText实现分割输入内容

    在项目中可能会有许多需要输入手机号码.银行卡号或者身份证号等内容的输入框.如果直接输入的话将会是一堆号码堆在一起,第一是不太美观,第二也容易出错,用户体验不太好.但是若将输入的号码按特定格式进行分割将会大大提高用户体验! 以下是对常用的号码进行简单封装的自定义输入框控件,方便我们在开发过程中使用: 该控件支持xml属性指定,也支持代码指定: 该控件支持类型分别为电话号码(000 0000 0000).银行卡号(0000 0000 0000 0000 000)和身份证号(000000 0000 0

  • Android TextWatcher监控EditText中的输入内容并限制其个数

    布局中EditText在android布局中经常用到,对EditText中输入的内容也经常需要进行限制,我们可以通过TextWatcher去观察输入框中输入的内容,作个笔记. 主布局: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:ori

  • Android如何禁止向EditText控件中输入内容详解

    前言 在Android开发中经常会遇到EditText控件,而在App开发过程中.遇到了这样一个问题.那就是Android EditText控件如何禁止往里面输入内容? 最开始找到修改版解决方法.但是当想输入的时候就有问题了.可以参考一下.但不建议这样写 EditText editText = (EditText) findViewById(R.id.editText1); editText.setKeyListener(null); 看到这个问题大家可能有点奇怪了.EditText的功能不就是

  • Android EditText实现输入金额类型详解

    前言 众所周知,Android中的editText默认的属性里面是没有金额类型的,所以要实现这个功能我们就必须自己动手丰衣足食.下面话不多说了,来一起看看详细的介绍吧. 一.EditText只允许输入数字.小数点. 首先要知道金额有两部分构成,整数部分和小数部分,要实现只输入数字和小数点很简单.自己查能很容易查到. 把type设置成InputType.TYPE_NUMBER_FLAG_DECIMAL|InputType.TYPE_CLASS_NUMBER 就行 那这样做有个缺点,小数部分可以有很

  • Android编程开发之EditText中不输入特定字符会显示相关提示信息的方法

    本文实例讲述了Android编程开发之EditText中不输入特定字符会显示相关提示信息的方法.分享给大家供大家参考,具体如下: 先看效果图: 源码如下: 布局文件: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="

  • Android实现EditText控件禁止输入内容的方法(附测试demo)

    本文实例讲述了Android实现EditText控件禁止输入内容的方法.分享给大家供大家参考,具体如下: 问题: android如何实现EditText控件禁止往里面输入内容? 修改版解决方法: EditText editText = (EditText) findViewById(R.id.editText1); editText.setKeyListener(null); 看到这个问题大家可能有点奇怪了,EditText的功能不就是往上面写入内容吗? 再者,如果真要禁止输入文本,在布局文件中

  • Android EditText限制输入字符类型的方法总结

    Android EditText限制输入字符类型的方法总结 前言: 最近的项目上需要限制EditText输入字符的类型,就把可以实现这个功能的方法整理了一下: 1.第一种方式是通过EditText的inputType来实现,可以通过xml或者Java文件来设置.假如我要设置为显示密码的形式,可以像下面这样设置: 在xml中 Android:inputType="textPassword" 在java文件中,可以用 myEditText.setInputType(InputType.TY

  • Android EditText限制输入字数的方法

    本文实例讲述了Android EditText限制输入字数的方法.分享给大家供大家参考,具体如下: //新浪微博字数限制 private static final int WEIBO_CONTENT_LENGTH_LIMITED = 140; //添加微博内容edittext mInputEditText.addTextChangedListener(mTextWatcher); private TextWatcher mTextWatcher = new TextWatcher() { pri

  • Android编程中EditText限制文字输入的方法

    本文实例讲述了Android编程中EditText限制文字输入的方法.分享给大家供大家参考,具体如下: Android的编辑框控件EditText在平常编程时会经常用到,有时候会对编辑框增加某些限制,如限制只能输入数字,最大输入的文字个数,不能输入一些非法字符等,这些需求有些可以使用android控件属性直接写在布局xml文件里,比如android:numeric="integer"(只允许输入数字): 对于一些需求,如非法字符限制(例如不允许输入#号,如果输入了#给出错误提示),做成

随机推荐