一个字符带下滑线的EditText
效果样式:

这个比较特别的editText是公司的一个新的需求,我也是在网上找了一下,然后看到了一篇博客然后修改成自己需要的样式。这种一般的思路就是在onDraw()方法绘制editText的特别的样式,如果输入里面的值是*这种特殊字符就只用直接绘制,如果需要输入进去的值则可以在onTextChanged方法中获取每一次更改editText值,在onDraw方法里一个个的绘制。
自定义的editText
package com.kkrs.selfedit; import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.text.InputFilter;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.EditText; import static android.graphics.Paint.ANTI_ALIAS_FLAG; /**
* Created by zd on 2018/11/27.
*/ public class InputView extends EditText {
private Context mContext;
/**
* 第一个圆开始绘制的圆心坐标
*/
private float startX;
private float startY; private float cX; int psdType = 0; /**
* 实心圆的半径
*/
private int radius = 10;
/**
* view的高度
*/
private int height;
private int width; /**
* 当前输入密码位数
*/
private int textLength = 0;
private int bottomLineLength;
/**
* 最大输入位数
*/
private int maxCount = 6;
/**
* 圆的颜色 默认BLACK
*/
private int circleColor = Color.BLACK;
/**
* 底部线的颜色 默认GRAY
*/
private int bottomLineColor = Color.GRAY; /**
* 分割线开始的坐标x
*/
private int divideLineWStartX; /**
* 分割线的宽度 默认2
*/
private int divideLineWidth = 2;
/**
* 竖直分割线的颜色
*/
private int divideLineColor = Color.GRAY;
private int focusedColor = Color.BLUE;
private RectF rectF = new RectF();
private RectF focusedRecF = new RectF(); private String texts = "";
/**
* 矩形边框的圆角
*/
private int rectAngle = 0;
/**
* 圆的画笔
*/
private Paint circlePaint;
/**
* 底部线的画笔
*/
private Paint bottomLinePaint; /**
* 需要对比的密码 一般为上次输入的
*/
private String mComparePassword = null; /**
* 当前输入的位置索引
*/
private int position = 0; private onPasswordListener mListener; public InputView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context; getAtt(attrs);
initPaint(); this.setBackgroundColor(Color.TRANSPARENT);
this.setCursorVisible(false);
this.setFilters(new InputFilter[]{new InputFilter.LengthFilter(maxCount)}); } private void getAtt(AttributeSet attrs) {
TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.PayPsdInputView);
maxCount = typedArray.getInt(R.styleable.PayPsdInputView_maxCount, maxCount);
circleColor = typedArray.getColor(R.styleable.PayPsdInputView_circleColor, circleColor);
bottomLineColor = typedArray.getColor(R.styleable.PayPsdInputView_bottomLineColor, bottomLineColor);
radius = typedArray.getDimensionPixelOffset(R.styleable.PayPsdInputView_radius, radius);
divideLineWidth = typedArray.getDimensionPixelSize(R.styleable.PayPsdInputView_divideLineWidth, divideLineWidth);
divideLineColor = typedArray.getColor(R.styleable.PayPsdInputView_divideLineColor, divideLineColor);
psdType = typedArray.getInt(R.styleable.PayPsdInputView_psdType, psdType);
rectAngle = typedArray.getDimensionPixelOffset(R.styleable.PayPsdInputView_rectAngle, rectAngle);
focusedColor = typedArray.getColor(R.styleable.PayPsdInputView_focusedColor, focusedColor); typedArray.recycle();
} /**
* 初始化画笔
*/
private void initPaint() { circlePaint = getPaint(5, Paint.Style.FILL, circleColor); bottomLinePaint = getPaint(2, Paint.Style.FILL, bottomLineColor); } /**
* 设置画笔
*
* @param strokeWidth 画笔宽度
* @param style 画笔风格
* @param color 画笔颜色
* @return
*/
private Paint getPaint(int strokeWidth, Paint.Style style, int color) {
Paint paint = new Paint(ANTI_ALIAS_FLAG);
paint.setStrokeWidth(strokeWidth);
paint.setStyle(style);
paint.setColor(color);
paint.setAntiAlias(true);
paint.setTextSize(40);
return paint;
} @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
height = h;
width = w; divideLineWStartX = w / maxCount; startX = w / maxCount / 2;
startY = h / 2; bottomLineLength = w / (maxCount + 2); rectF.set(0, 0, width, height); } @Override
protected void onDraw(Canvas canvas) {
//不删除的画会默认绘制输入的文字
// super.onDraw(canvas);
drawBottomBorder(canvas); switch (psdType){
case 0:
char[] cc;
cc=texts.toCharArray();
for (int i = 0; i < cc.length; i++) {
Log.e("sys","cc="+cc[i]);
canvas.drawText(cc[i]+"",startX + i * 2 * startX,
startY,circlePaint);
}
break;
case 1:
drawPsdCircle(canvas); break;
}
} /**
* 画密码实心圆
*
* @param canvas
*/
private void drawPsdCircle(Canvas canvas) {
for (int i = 0; i < textLength; i++) {
canvas.drawCircle(startX + i * 2 * startX,
startY,
radius,
circlePaint);
}
}
/**
* 画底部显示的分割线
*
* @param canvas
*/
private void drawBottomBorder(Canvas canvas) { for (int i = 0; i < maxCount; i++) {
cX = startX + i * 2 * startX;
canvas.drawLine(cX - bottomLineLength / 2,
height,
cX + bottomLineLength / 2,
height, bottomLinePaint);
}
} @Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
super.onTextChanged(text, start, lengthBefore, lengthAfter);
this.position = start + lengthAfter;
textLength = text.toString().length();
texts = text.toString();
Log.e("onTextChanged",text.toString()); if (textLength == maxCount) {
if (mListener != null) {
if (TextUtils.isEmpty(mComparePassword)) {
mListener.inputFinished(getPasswordString());
} else {
if (TextUtils.equals(mComparePassword, getPasswordString())) {
mListener.onEqual(getPasswordString());
} else {
mListener.onDifference(mComparePassword, getPasswordString());
}
}
}
} invalidate(); } @Override
protected void onSelectionChanged(int selStart, int selEnd) {
super.onSelectionChanged(selStart, selEnd); //保证光标始终在最后
if (selStart == selEnd) {
setSelection(getText().length());
}
} /**
* 获取输入的密码
*
* @return
*/
public String getPasswordString() {
return getText().toString().trim();
} public void setComparePassword(String comparePassword, onPasswordListener listener) {
mComparePassword = comparePassword;
mListener = listener;
} public void setComparePassword(onPasswordListener listener) {
mListener = listener;
} public void setComparePassword(String psd) {
mComparePassword = psd;
} /**
* 清空密码
*/
public void cleanPsd() {
setText("");
} /**
* 密码比较监听
*/
public interface onPasswordListener {
void onDifference(String oldPsd, String newPsd); void onEqual(String psd); void inputFinished(String inputPsd);
}
}
在xml的用法:
<?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"
xmlns:tools="http://schemas.android.com/tools"
xmlns:psd="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
> <com.kkrs.selfedit.InputView
android:id="@+id/pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginTop="20dp"
android:inputType="number"
psd:maxCount="6"
psd:psdType="pwd"/> <com.kkrs.selfedit.InputView
android:id="@+id/phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginTop="20dp"
android:inputType="number"
psd:maxCount="11"
psd:psdType="phone"/> </LinearLayout>
github:https://github.com/tempest1/SelfEdit
一个字符带下滑线的EditText的更多相关文章
- sql 字符带下划线匹配问题
SQL 中 _下划线 作用是 匹配一个任意字符. 如果我们要去掉下划线的作用 单纯只用作一个字符则需要转义成 like '%\_%' escape '\' 字段 1.order_qrsc 2.o ...
- Android实现带下划线的EditText(BUG修正)
之前写了一个关于实现EditText显示下划线的例子,发现仍然存在一些问题,在此继续探索,原文链接:http://www.cnblogs.com/ayqy/p/3599414.html (零)另一个b ...
- delphi 仅带下划线的TEdit控件
在做录入框的时候,很希望有一个只带下划线的文本框,网上介绍的很多,有自己做组件的,须不知Delphi下只需要简单设置几个属性即可达到目的.
- ssh框架从页面传中文发生乱码时怎么解决,就是添加一个字符编码拦截器。用springframework自带的便可
ssh框架从页面传中文发生乱码时怎么解决,就是添加一个字符编码拦截器.用springframework自带的便可
- C++学习45 流成员函数put输出单个字符 cin输入流详解 get()函数读入一个字符
在程序中一般用cout和插入运算符“<<”实现输出,cout流在内存中有相应的缓冲区.有时用户还有特殊的输出要求,例如只输出一个字符.ostream类除了提供上面介绍过的用于格式控制的成员 ...
- utf-8的中文,一个字符占几个字节
https://blog.csdn.net/kindsuper_liu/article/details/80202150 英文字母和中文汉字在不同字符集编码下的字节数英文字母:·字节数 : 1;编码: ...
- utf-8的中文是一个字符占几个字节
utf-8的中文是一个字符占几个字节 英文字母和中文汉字在不同字符集编码下的字节数英文字母:·字节数 : 1;编码:GB2312 字节数 : 1;编码:GBK 字节数 : 1;编码:GB18030 字 ...
- Android带加减的edittext
看了网上这样自带加减的edittext写得好复杂,还有各种监听事件,我觉得没有必有.于是我自己写了一个. 我这个edittext仅仅限制整数,每次加减1. public class TestEditT ...
- php 去掉字符串的最后一个字符
原字符串1,2,3,4,5,6, 去掉最后一个字符",",最终结果为1,2,3,4,5,6 代码如下: $str = "1,2,3,4,5,6,"; $news ...
随机推荐
- 强化学习(十九) AlphaGo Zero强化学习原理
在强化学习(十八) 基于模拟的搜索与蒙特卡罗树搜索(MCTS)中,我们讨论了MCTS的原理和在棋类中的基本应用.这里我们在前一节MCTS的基础上,讨论下DeepMind的AlphaGo Zero强化学 ...
- 号称“新至强,可拓展,赢当下”的Xeon可拓展处理器有多逆天?
目前企业数据中心正在发生重大变化,许多企业正在经历基于在线服务和数据的广泛转型.他们将这些数据用于功能强大的人工智能和分析应用程序,这些应用程序可以将其转化为改变业务的洞察力,然后推出可以使这些洞察力 ...
- openlayers4 入门开发系列之地图标绘篇(附源码下载)
前言 openlayers4 官网的 api 文档介绍地址 openlayers4 api,里面详细的介绍 openlayers4 各个类的介绍,还有就是在线例子:openlayers4 官网在线例子 ...
- Hi3516EV300专业型HD IP Camera SoC
Hi3516EV300芯片特点: 处理器内核 ARM Cortex A7@ 900MHz,32KB I-Cache,32KB D-Cache /128KB L2 cache 支持 Neon 加速,集成 ...
- 2018-02-24 项目/教程中使用母语命名的"问题"
早先试图找使用中文命名代码的项目, 但所获寥寥: 索引: 用中文编写代码的实用开源项目 · Issue #6 · program-in-chinese/overview. 更不用说教程了: 索引: 用 ...
- Python开发【内置函数篇】re正则表达式
一.简介 正则表达式本身是一种小型的.高度专业化的编程语言,而在python中,通过内嵌集成re模块,程序媛们可以直接调用来实现正则匹配.正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎 ...
- CORS的简单理解
去年我在做一个项目,是关于标签打印的,它就是一个Windows程序,提供标签打印功能,由其它程序(包括网站)告诉它需要打印怎样的标签,它就出标签,这个“告诉它需要怎样的标签”的过程,是通过HTTP的P ...
- kafka的设计
1.动机 设计 kafka 初衷,作为统一平台处理大公司的实时数据.所以 必须具有如下特性: 支持海量数据 高吞吐量 低延迟(实时性) 支持分区,分布式 容错 2.持久化 kafka 高度依赖 文件系 ...
- Mybatis之旅第三篇-SqlMapConfig.xml全局配置文件解析
一.前言 刚换工作,为了更快的学习框架和了解业务,基本每天都会加班,导致隔了几天没有进行总结,心里总觉得不安,工作年限越长越感到学习的重要性,坚持下去!!! 经过前两篇的总结,已经基本掌握了mybat ...
- 限定项目的 Node.js 版本
限定项目运行所需的 Node.js 版本可保证项目在一个稳定可预期的环境中运行,减少不必要的故障.甚至有些依赖库只能工作于某些版本下.同时,不加以限制的话,在多人合作的项目中恐怕会引起环境不一致带来的 ...