看到一些应用中的点赞觉得挺有意思,具体效果大概就是这个样子
然后我仿写了下,效果差不多,代码比较简单就不过多说明了
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();
}
}