关于Ali Muzaffar大神的AnimatedEditText的优化
2016-03-31 11:27
459 查看
关于Ali Muzaffar大神的AnimatedEditText的优化
今天在android论坛上偶然发现一个关于android editText文本输入框输入带动作的文本的demo。于是就去git上下载了这个demo自己研究,demo地址:[ https://github.com/alphamu/AnimatedEditText ],实现效果:通过其attrs.xml的定义:
<declare-styleable name="AnimatedEditText"> <attr name="animationType" format="enum"> <enum name="fromBottom" value="0" /> <enum name="fromRight" value="1" /> <enum name="fromMiddle" value="2" /> <enum name="popIn" value="3" /> </attr> <attr name="textMask" format="string" /> </declare-styleable>
支持4中文本输入动作。
在使用时出现了一个问题,就是在追加文本的时候可以显示动作,但是如果是插入文本的话,就没有这个动作了。于是查看AnimatedEditText的实现类。查看其onTextChanged方法
@Override protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { super.onTextChanged(text, start, lengthBefore, lengthAfter); String added = TextUtils.substring(text, start, start + lengthAfter); int textLength = text.length(); if (lengthAfter == 1 && added.equals(" ")) { return; } if (lengthBefore == lengthAfter) { //either swipe/autosuggest did something, or someone edit or paste something //of the same length. mStart = textLength - 1; mEnd = textLength; return; } if (lengthBefore < lengthAfter && textLength == start + lengthAfter) { //if we are adding text & adding it to the end of the line. if (lengthBefore == 0) { //normal case when tapping keyboard. mStart = start; mEnd = start + lengthAfter; } else { //if using auto suggest, it can result in animating the whole word every //time a character is tapped. This forces only the last character to animate. mStart = textLength - 1; mEnd = textLength; } switch (mAnimationType) { case RIGHT_TO_LEFT: animateInFromRight(); break; case MIDDLE_UP: animateInFromMiddle(); break; case POP_IN: animatePopIn(); break; default: animateInFromBottom(); } } else { mStart = 0; mEnd = text.length(); } }
观察其第三个IF判断,在当前的文本长度 == 新添加的文本长度+新添加文本的起始位置的情况下,调用自定义的animate。这里把插入的情况给忽略掉了,导致了插入的时候不会触发自定义animate。总结一下解决办法,这个解决办法是处理popIn的情况,其他情况类似。
popIn的绘制代码:
private void drawGravityLeft(Canvas canvas) { String fixedText = getFixedText(); float fixedTextWidth = mPaint.measureText(fixedText); float startX = getCompoundPaddingLeft(); canvas.drawText(fixedText, startX, getLineBounds(0, null), mPaint); canvas.drawText(getFullText(), mStart, mEnd, startX + fixedTextWidth + mRightOffset, getLineBounds(0, null) + mBottomOffset, mAnimPaint); }
插入文本的情况为 新添加的文本长度+插入位置 <= 当前文本长度(添加也是插入的一种情况)
修改在绘制popIn动作的代码(如果不修改此处代码,会出现只会绘制插入代码的位置之前的代码)
通过上述的要点可以看出,保证当前插入文本的正确绘制和插入文本位置之后的文本的正确绘制是要点:
/** * @param canvas * @author Muzaffar edit by GMF */ private void drawGravityLeft(Canvas canvas) { String fixedText = getFixedText(); float fixedTextWidth = mPaint.measureText(fixedText); float startX = getCompoundPaddingLeft(); canvas.drawText(fixedText, startX, getLineBounds(0, null), mPaint); CharSequence cs = getFullText(); canvas.drawText(cs, mStart, mEnd, startX + fixedTextWidth + mRightOffset, getLineBounds(0, null) + mBottomOffset, mAnimPaint); String rightText = cs.subSequence(mEnd,cs.length()).toString(); String leftText = cs.subSequence(mStart,mEnd).toString(); float leftTextWidth = mPaint.measureText(leftText + fixedText); canvas.drawText(rightText,startX + leftTextWidth, getLineBounds(0,null),mPaint); }
获取插入文本位置之后的文本,获取插入文本与插入前文本的长度,通过这个长度来确定插入文本之后的文本的位置。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories