您的位置:首页 > 移动开发 > Android开发

关于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);
}


获取插入文本位置之后的文本,获取插入文本与插入前文本的长度,通过这个长度来确定插入文本之后的文本的位置。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  关于Ali-Muza android