irpas技术客

Android TextView 仿动控件_MarkRZJ

大大的周 722

看到一些应用中的点赞觉得挺有意思,具体效果大概就是这个样子

50buq-l34h1.gif

然后我仿写了下,效果差不多,代码比较简单就不过多说明了

import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.View; public class LikeView extends View { private static final String DEFAULT_TEXT_COLOR = "#cccccc"; private static final int ANIM_TIME = 300; private int mCurrValue; // true 字符相同,false 不同 private boolean[] mArrayStatus; private Paint mTextPaint; private int mTextSize; private int mTextOffY; private boolean mIsLike; private float mCurrOffsetY; private int mSingleTextWidth; public LikeView(Context context) { super(context); init(context); } public LikeView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(context); } public LikeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private void init(Context context) { mTextSize = sp2px(context, 16f); mTextOffY = mTextSize / 2; mTextPaint = new Paint(); mTextPaint.setAntiAlias(true); mTextPaint.setTextSize(mTextSize); mTextPaint.setColor(Color.parseColor(DEFAULT_TEXT_COLOR)); mSingleTextWidth = measureWidth("9"); } private int sp2px(Context context, float spValue) { final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; return (int) (spValue * fontScale + 0.5f); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = measureWidth(String.valueOf(mCurrValue)) + getPaddingLeft() + getPaddingRight(); int height = mTextSize + getPaddingTop() + getPaddingBottom(); if (View.MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) { width = Math.max(width, MeasureSpec.getSize(widthMeasureSpec)); } if (View.MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) { height = Math.max(width, MeasureSpec.getSize(heightMeasureSpec)); } setMeasuredDimension(width, height); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); String content = String.valueOf(mCurrValue); int offX = getPaddingLeft(); int offY = getPaddingTop() + mTextSize; if (null == mArrayStatus || mArrayStatus.length != content.length()) { canvas.drawText(content, offX, offY, mTextPaint); } else { int currLeft = offX; int strLength = content.length() - 1; for (int i = 0, y = content.length(); i < y; i++) { if (mArrayStatus[strLength]) { canvas.drawText(String.valueOf(content.charAt(i)), currLeft, offY, mTextPaint); } else { canvas.drawText(String.valueOf(content.charAt(i)), currLeft, offY + mCurrOffsetY, mTextPaint); } currLeft += mSingleTextWidth; strLength--; } } } private int measureWidth(String content) { return (int) Math.ceil(mTextPaint.measureText(content)); } public void setCurrValue(int currValue) { this.mCurrValue = currValue; requestLayout(); } public void setLike() { setLike(!mIsLike); } public void setLike(boolean isLike) { setLike(isLike, 1); } public void setLike(boolean isLike, int value) { this.mIsLike = isLike; int lastValue = mCurrValue; if (isLike) { lastValue += value; } else { lastValue -= value; } findDiff(String.valueOf(mCurrValue), String.valueOf(lastValue)); mCurrValue = lastValue; startAnim(); } private void findDiff(String currStr, String lastStr) { if (null == currStr || null == lastStr || currStr.equals(lastStr)) { return; } int currStrLength = currStr.length() - 1; int lastStrLength = lastStr.length() - 1; int maxLength = Math.max(currStr.length(), lastStr.length()); mArrayStatus = new boolean[maxLength]; for (int i = 0; i < maxLength; i++) { if (currStrLength >= 0 && lastStrLength >= 0) { char c1 = currStr.charAt(currStrLength); char c2 = lastStr.charAt(lastStrLength); mArrayStatus[i] = c1 == c2; currStrLength--; lastStrLength--; } else { mArrayStatus[i] = false; } } } public void setTextOffY(float offsetY) { float value = mTextOffY * offsetY; this.mCurrOffsetY = mIsLike ? value : -value; invalidate(); } private void startAnim() { @SuppressLint("ObjectAnimatorBinding") ObjectAnimator anim = ObjectAnimator.ofFloat(this, "textOffY" , 1, 0); anim.setDuration(ANIM_TIME); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); mArrayStatus = null; mCurrOffsetY = 0; } }); anim.start(); } }


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #Android #textview #仿动控件