文档章节

实现EditText的分割输入内容效果

 易水寒521
发布于 2015/06/23 16:39
字数 861
阅读 345
收藏 7
 package com.example.sequencenumber;
import android.content.Context;
import android.content.res.TypedArray;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.View;
import android.widget.EditText;
/**
 * 分割输入框
 * 
 * @author Administrator
 * 
 */
public class DivisionEditText extends EditText {
 /* 内容数组 */
 private String[] text;
 /* 数组实际长度 (内容+分隔符) */
 private Integer length;
 /* 允许输入的长度 */
 private Integer totalLength;
 /* 每组的长度 */
 private Integer eachLength;
 /* 分隔符 */
 private String delimiter;
 /* 占位符 */
 private String placeHolder;
 public DivisionEditText(Context context) {
  super(context);
 }
 public DivisionEditText(Context context, AttributeSet attrs) {
  super(context, attrs);
  try {
   // 初始化属性
   TypedArray typedArray = context.obtainStyledAttributes(attrs,
     R.styleable.EditText);
   this.totalLength = typedArray.getInteger(
     R.styleable.EditText_totalLength, 0);
   this.eachLength = typedArray.getInteger(
     R.styleable.EditText_eachLength, 0);
   this.delimiter = typedArray
     .getString(R.styleable.EditText_delimiter);
   if (this.delimiter == null || this.delimiter.length() == 0) {
    this.delimiter = "-";
   }
   this.placeHolder = typedArray
     .getString(R.styleable.EditText_placeHolder);
   if (this.placeHolder == null || this.placeHolder.length() == 0) {
    this.placeHolder = " ";
   }
   typedArray.recycle();
   // 初始化
   init();
   // 内容变化监听
   this.addTextChangedListener(new DivisionTextWatcher());
   // 获取焦点监听
   this.setOnFocusChangeListener(new DivisionFocusChangeListener());
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 public DivisionEditText(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
 }
 /**
  * 初始化
  */
 public void init() {
  // 总共分几组
  int groupNum = 0;
  // 如果每组长度(除数)不为0,计算
  if (this.eachLength != 0) {
   groupNum = this.totalLength / this.eachLength;
  }
  // 实际长度
  length = this.totalLength + this.eachLength != 0 ? this.totalLength
    + groupNum - 1 : 0;
  // 初始化数组
  text = new String[this.length];
  // 如果数组大小大于0,初始化里面内容
  // 空格占位,分隔符占位
  if (length > 0) {
   for (int i = 0; i < length; i++) {
    if (i != 0 && (i + 1) % (this.eachLength + 1) == 0) {
     text[i] = this.delimiter;
    } else {
     text[i] = placeHolder;
    }
   }
   // 设置文本
   mySetText();
   // 设置焦点
   mySetSelection();
  }
 }
 /**
  * 获取结果
  * 
  * @return
  */
 public String getResult() {
  StringBuffer buffer = new StringBuffer();
  for (String item : text) {
   if (!placeHolder.equals(item) && !delimiter.equals(item)) {
    buffer.append(item);
   }
  }
  return buffer.toString();
 }
 /**
  * 文本监听
  * 
  * @author Administrator
  * 
  */
 private class DivisionTextWatcher implements TextWatcher {
  @Override
  public void afterTextChanged(Editable s) {
  }
  @Override
  public void beforeTextChanged(CharSequence s, int start, int count,
    int after) {
  }
  @Override
  public void onTextChanged(CharSequence s, int start, int before,
    int count) {
   // 如果当前长度小于数组长度,认为使用退格
   if (s.length() < length) {
    // 光标所在位置
    int index = DivisionEditText.this.getSelectionStart();
    // 删除的字符
    String deleteStr = text[index];
    // 如果是分隔符,删除分隔符前一个
    if (delimiter.equals(deleteStr)) {
     index--;
    }
    // 置空
    text[index] = placeHolder;
    // 查看前一个是否为分隔符
    if (index - 1 >= 0) {
     if (delimiter.equals(text[index - 1])) {
      index--;
     }
    }
    // 设置文本
    mySetText();
    // 设置焦点
    mySetSelection(index);
   }
   // 只能一个一个字符输入
   if (count == 1) {
    // 从光标起始,是否还有空的位置
    int index = isBlank(DivisionEditText.this.getSelectionStart());
    // 如果还有
    if (index != -1) {
     // 输入框内的字符串
     String allStr = s.toString();
     // 输入的字符串
     String inputStr = allStr.substring(start, start + count);
     // 替换占位符
     text[index] = inputStr;
    }
    // 设置文本
    mySetText();
    // 设置焦点
    mySetSelection();
   }
  }
 }
 /**
  * 获取焦点监听
  * 
  * @author Administrator
  * 
  */
 private class DivisionFocusChangeListener implements OnFocusChangeListener {
  @Override
  public void onFocusChange(View v, boolean hasFocus) {
   if (hasFocus) {
    // 设置焦点
    mySetSelection(0);
   }
  }
 }
 /**
  * 设置文本
  * 
  * @param text
  */
 private void mySetText() {
  StringBuffer buffer = new StringBuffer();
  for (String item : text) {
   buffer.append(item);
  }
  // 设置文本
  setText(buffer);
 }
 /**
  * 设置焦点
  * 
  * @param text
  */
 private void mySetSelection() {
  mySetSelection(fullSelection());
 }
 /**
  * 设置焦点
  * 
  * @param text
  */
 private void mySetSelection(int index) {
  DivisionEditText.this.setSelection(index);
 }
 /**
  * 从光标位置起始,检查后面是否还有空的占位符
  * 
  * @param text
  * @param selection
  * @return
  */
 private int isBlank(int selection) {
  int index = -1;
  for (int i = selection - 1; i < length; i++) {
   if (placeHolder.equals(text[i])) {
    index = i;
    break;
   }
  }
  return index;
 }
 /**
  * 最后一个不空的字符后的光标位置
  * 
  * @param text
  * @return
  */
 private int fullSelection() {
  int index = 0;
  for (int i = 0; i < length; i++) {
   if (!placeHolder.equals(text[i]) && !delimiter.equals(text[i])) {
    index = i + 1;
   }
  }
  return index;
 }
 public Integer getTotalLength() {
  return totalLength;
 }
 public void setTotalLength(Integer totalLength) {
  this.totalLength = totalLength;
 }
 public Integer getEachLength() {
  return eachLength;
 }
 public void setEachLength(Integer eachLength) {
  this.eachLength = eachLength;
 }
 public String getDelimiter() {
  return delimiter;
 }
 public void setDelimiter(String delimiter) {
  this.delimiter = delimiter;
 }
 public String getPlaceHolder() {
  return placeHolder;
 }
 public void setPlaceHolder(String placeHolder) {
  this.placeHolder = placeHolder;
 }
}

attrs.xml

 <?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="EditText">
        <!-- 总共输入长度 -->
        <attr name="totalLength" format="integer" />
        <!-- 每组的长度 -->
        <attr name="eachLength" format="integer" />
        <!-- 分隔符 -->
        <attr name="delimiter" format="string" />
        <!-- 占位符 -->
        <attr name="placeHolder" format="string" />
    </declare-styleable>
</resources>

在布局文件中使用

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:fsms="http://schemas.android.com/apk/res/com.example.sequencenumber"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <com.example.sequencenumber.DivisionEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        fsms:delimiter="-"
        fsms:eachLength="5"
        fsms:placeHolder="0"
        fsms:totalLength="25" />
</LinearLayout>

© 著作权归作者所有

共有 人打赏支持
粉丝 0
博文 130
码字总数 120077
作品 0
虹口
EditText输入电话号码、银行卡号自动添加空格分割

功能介绍: ①EditText输入电话号码、银行卡号自动添加空格分割 ②自定义分割符号、分割模式 ③右侧默认添加清除功能图标,可自定义图标并设置点击监听,配合PopupWindow等进行输入提示 ④仿...

拼一把
2015/11/26
125
0
急!android的notifydatasetchanged第二次查询没反应的问题。

这个问题郁闷我接近两天了,很郁闷,求大神帮忙。 截图如下 实现效果是listview外加一个edittext在最上面,editText.addTextChangedListener(new TextWatcher() {};adapter实现了filterable接...

happycodinggirl
2013/05/21
661
0
学习笔记-Android之ListView随EditText输入内容动态改变

在学习过程之中经常用到各种词典发现再输入过程中有类似AutocompleteTextView的随着在EditText输入内容ListView动态变化的效果 自己试着简单实现以下 实现这种效果主要用到的一个类TextWatch...

WonderfulLife
2012/09/12
0
2
Android开发之EditText属性详解

1、EditText输入的文字为密码形式的设置 (1)通过.xml里设置: 把该EditText设为:android:password="true" // 以”.”形式显示文本 (2)在代码里设置: 通过设置EditText的setTransformation...

的书法上的
2014/07/28
0
0
实现4个数字一组分隔显示的数字输入框

前言 很悲剧,对于输入框而言,有时我们不得不实现几个数字后就出现一个空格的情况,这是为了方便用户观察。那么今天就讲讲这中输入框CrEditText的实现吧。 今天涉及内容: 原理分析 CrEdit...

奔跑的佩恩
07/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

jetbrains系产品IDEA:mac上面提示快捷键设置

原因 由于Mac上面的Ctrl+空格变成输入法切换的快捷键,在使用IDEA的过程中,代码提示很不方便,需要使用option+/这种传统eclipse上面的代码提示快捷键作为主要快捷键。 怎么修改? 移除【opt...

亚林瓜子
34分钟前
0
0
Exclipse 输出结果时换行

System.out.println(f1 + "\n" + d1 + "\n" + d2);

笑丶笑
35分钟前
1
0
怎样治疗标签不能触发onblur事件

I realize this was over a year ago, but it showed up for me in Google while trying to solve this same issue. It seems Chrome does not consider some elements, like body and ancho......

Weijuer
38分钟前
0
0
vue常见库安装

移动设备上的浏览器默认会在用户点击屏幕大约延迟300毫秒后才会触发点击事件,这是为了检查用户是否在做双击。为了能够立即响应用户的点击事件,才有了FastClick。 安装fastclick npm insta...

林夏夕
40分钟前
0
0
kafka 教程(三) kafka Java API 编程

下午写

MrPei
40分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部