import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 找到控件
final TypingView typingView = findViewById(R.id.typing_view);
// 给控件设置聊天背景图(这里使用.9图片拉伸)
typingView.setBackgroundResource(R.drawable.bg_chat);
// 给控件设置画笔颜色
typingView.setPaintColor(Color.parseColor("#cccccc"));
// 给控件设置动画延迟时间
typingView.setDelayMilliseconds(500);
// 给控件设置视图大小(宽度和高度)
typingView.setViewSize(getResources().getDimension(R.dimen.width254px),
getResources().getDimension(R.dimen.width116px));
// 设置小圆的半径
typingView.setSmallRadius(getResources().getDimension(R.dimen.width8px));
// 设置大圆的半径
typingView.setBigRadius(getResources().getDimension(R.dimen.width12px));
// 设置左侧内部间距
typingView.setPaddingLeft(getResources().getDimension(R.dimen.width12px));
// 开始动画
typingView.start();
// 3秒之后隐藏视图
typingView.postDelayed(new Runnable() {
@Override
public void run() {
typingView.stop();
}
}, 1000 * 3);
}
}
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* 自定义“正在输入”动画视图
*/
public class TypingView extends View {
// 画笔
private Paint mPaint;
// 大半径
private float bigRadius;
// 小半径
private float smallRadius;
// 设置动画延迟时间
private long delayMilliseconds;
// 视图宽度
private float viewWidth;
// 视图高度
private float viewHeight;
// 左间距
private float paddingLeft;
// 是否启动
private volatile boolean isStart;
// 当前大圆位置
private volatile int position = 0;
public TypingView(Context context) {
super(context);
init();
}
public TypingView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public TypingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isInEditMode()) {
return;
}
if (isStart) {
position = position + 1;
if (position < 0 || position > 2) {
position = 0;
}
// 圆距
final float distance = bigRadius * 2;
// 循环画圆
for (int i = 0; i < 3; i++) {
float radius;
if (i == position) {
radius = bigRadius;
} else {
radius = smallRadius;
}
// 圆心的x坐标 = (控件宽度 - 3个大圆直径 - 两个圆距) / 2 + i * (大圆直径 + 圆距) + 从左向右平移的距离
float radiusX = (viewWidth - bigRadius * 2 * 3 - distance * 2) / 2 + i * (bigRadius * 2 + distance) + paddingLeft;
// 圆心的Y坐标 = 控件高度 / 2
float radiusY = viewHeight / 2;
canvas.drawCircle(radiusX, radiusY, radius, mPaint);
}
postInvalidateDelayed(delayMilliseconds);
}
}
/**
* 初始化数据
*/
private void init() {
isStart = false;
bigRadius = 0;
smallRadius = 0;
viewWidth = 0;
viewHeight = 0;
paddingLeft = 0;
delayMilliseconds = 300;
if (mPaint == null) {
mPaint = new Paint();
// 防抖动
mPaint.setDither(true);
// 抗锯齿
mPaint.setAntiAlias(true);
// 设置绘画的连接
mPaint.setStrokeJoin(Paint.Join.ROUND);
// 设置画笔颜色
mPaint.setColor(Color.BLACK);
}
}
/**
* 设置视图大小
*
* @param viewWidth
* @param viewHeight
*/
public void setViewSize(float viewWidth, float viewHeight) {
this.viewWidth = viewWidth;
this.viewHeight = viewHeight;
}
/**
* 设置大圆半径
*
* @param bigRadius
*/
public void setBigRadius(float bigRadius) {
this.bigRadius = bigRadius;
}
/**
* 设置小圆半径
*
* @param smallRadius
*/
public void setSmallRadius(float smallRadius) {
this.smallRadius = smallRadius;
}
/**
* 设置左间距(例如给控件设置带箭头聊天框的背景图时,又想让动画居中显示,我们可以设置该属性为正/负来实现)
*
* @param paddingLeft
*/
public void setPaddingLeft(float paddingLeft) {
this.paddingLeft = paddingLeft;
}
/**
* 设置画笔颜色
*
* @param color
*/
public void setPaintColor(int color) {
if (mPaint != null) {
mPaint.setColor(color);
}
}
/**
* 设置动画延迟时间
*
* @param delayMilliseconds
*/
public void setDelayMilliseconds(long delayMilliseconds) {
this.delayMilliseconds = delayMilliseconds;
}
/**
* 开始
*/
public synchronized void start() {
if (!isStart) {
isStart = true;
postInvalidate();
setVisibility(View.VISIBLE);
}
}
/**
* 停止
*/
public synchronized void stop() {
if (isStart) {
isStart = false;
postInvalidate();
setVisibility(View.GONE);
}
}
}
文中所用.9图:
运行效果图: