SpannableStringBuilder使用注意
连续调用setSpan时参数Object what不能使用同一个引用
否则只有最后一个设置有效
https://blog.csdn.net/BigBoySunshine/article/details/48706451
TextView字体大小自适应
android:autoSizeMaxTextSize="12sp"
android:autoSizeMinTextSize="4sp"
android:autoSizeTextType="uniform"
二阶贝塞尔曲线动画效果
/**
* 贝塞尔曲线动画view
* 传入起始点重点坐标
*/
public class BezierAnimatorView extends AppCompatTextView implements ValueAnimator.AnimatorUpdateListener {
public static final int VIEW_SIZE = 24;
private static final int ANIMATOR_DURATION = 500;
protected Context mContext;
protected Paint mPaint4Circle;
protected int radius;
protected Point startPosition;
protected Point endPosition;
public BezierAnimatorView(Context context) {
this(context, null);
}
public BezierAnimatorView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BezierAnimatorView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
mPaint4Circle = new Paint();
mPaint4Circle.setColor(Color.parseColor("#FFDF6F"));
mPaint4Circle.setAntiAlias(true);
setGravity(Gravity.CENTER);
setText("1");
setTextColor(Color.WHITE);
setTextSize(12);
}
public void setStartPosition(Point startPosition) {
startPosition.y -= 10;
this.startPosition = startPosition;
}
public void setEndPosition(Point endPosition) {
this.endPosition = endPosition;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int PX4SIZE = AndroidUtil.dp2px(mContext, VIEW_SIZE);
setMeasuredDimension(PX4SIZE, PX4SIZE);
radius = PX4SIZE / 2;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, radius, mPaint4Circle);
super.onDraw(canvas);
}
public void startBeizerAnimation() {
if (startPosition == null || endPosition == null) return;
int pointX = (startPosition.x + endPosition.x) / 2;
int pointY = startPosition.y - AndroidUtil.dp2px(mContext, 100f);
Point controllPoint = new Point(pointX, pointY);
BezierEvaluator bezierEvaluator = new BezierEvaluator(controllPoint);
ValueAnimator anim = ValueAnimator.ofObject(bezierEvaluator, startPosition, endPosition);
anim.addUpdateListener(this);
anim.setDuration(ANIMATOR_DURATION);
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
ViewGroup viewGroup = (ViewGroup) getParent();
viewGroup.removeView(BezierAnimatorView.this);
}
});
anim.setInterpolator(new AccelerateDecelerateInterpolator());
anim.start();
}
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Point point = (Point) animation.getAnimatedValue();
setX(point.x);
setY(point.y);
invalidate();
}
public class BezierEvaluator implements TypeEvaluator<Point> {
private Point controllPoint;
public BezierEvaluator(Point controllPoint) {
this.controllPoint = controllPoint;
}
@Override
public Point evaluate(float t, Point startValue, Point endValue) {
int x = (int) ((1 - t) * (1 - t) * startValue.x + 2 * t * (1 - t) * controllPoint.x + t * t * endValue.x);
int y = (int) ((1 - t) * (1 - t) * startValue.y + 2 * t * (1 - t) * controllPoint.y + t * t * endValue.y);
return new Point(x, y);
}
}
}