欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android EditText实现分割输入内容

程序员文章站 2023-01-05 21:29:44
在项目中可能会有许多需要输入手机号码、银行卡号或者身份证号等内容的输入框。如果直接输入的话将会是一堆号码堆在一起,第一是不太美观,第二也容易出错,用户体验不太好。但是若将输...

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

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

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

效果图

Android EditText实现分割输入内容

自定义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>

项目地址:传送门

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