关于Ali Muzaffar大神的AnimatedEditText的优化

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

获取插入文本位置之后的文本,获取插入文本与插入前文本的长度,通过这个长度来确定插入文本之后的文本的位置。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值