前言:
前段时间公司业务不忙,每天无所事事,明明知道有很多要学的东西,却又不知道从何做起,感觉很不踏实,于是想管理规划下自己的时间。精挑细选下,看中了365日历,每天安排好时间,每个时间段学什么做什么,做起事来有条不紊,感觉充实多了。建议小伙伴们也要选择一种合适的时间管理工具,管理规划好时间,fighting。sorry,跑题了。
今天刷新日历,由于网络一时不畅,看到了加载动画,打算做个练练手,附一张静态图看效果:
就四个小球旋转,往里往外晃动。
概要:
本文都是一些绘图的基本知识,主要会涉及到绘图里面的一个旋转画布的概念,可以自己去了解下相关内容,文中不会做太详细的介绍。
正文:
首先分析一下需要自定义的属性:小球的半径radiu,四个球的颜色值,每个球偏移中心轴的距离。
我们先自定义好属性:
/*小圆半径*/
private int radiu;
/*四个球颜色值*/
private int color_one;
private int color_two;
private int color_three;
private int color_four;
/*偏移中心轴距离*/
private int offset;
//绘图工具
private Paint mPaint;
public MyView(Context context) {
this(context,null);
}
public MyView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.MyViewAttrs,defStyleAttr,0);
radiu = ta.getInt(R.styleable.MyViewAttrs_radiu,30);
color_one = ta.getColor(R.styleable.MyViewAttrs_color_one, Color.BLACK);
color_two = ta.getColor(R.styleable.MyViewAttrs_color_two, Color.BLACK);
color_three = ta.getColor(R.styleable.MyViewAttrs_color_three, Color.BLACK);
color_four = ta.getColor(R.styleable.MyViewAttrs_color_four, Color.BLACK);
offset = ta.getInt(R.styleable.MyViewAttrs_offset,50);
ta.recycle();
mPaint = new Paint();
mPaint.setStrokeWidth(3);
mPaint.setAntiAlias(true);
}
然后将自定义的VIew引入到我们的布局文件中,设置对应的属性值:
//View的宽高
private int mWidth,mHeight;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if(widthMode == MeasureSpec.EXACTLY){
mWidth = widthSize;
}else{
mWidth = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,400,getResources().getDisplayMetrics());
}
if(heightMode == MeasureSpec.EXACTLY){
mHeight = heightSize;
}else{
mHeight = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,400,getResources().getDisplayMetrics());
}
setMeasuredDimension(mWidth,mHeight);
}
好了,到这里我们的准备工作已经完成,我们把View的中心点作为x,y轴的中心轴,四个球分别在x轴正负,y轴正负偏移相同距离。首先我们先绘制静态的小球:
/*四个球*/
mPaint.setColor(color_one);
canvas.drawCircle(mWidth/2-offset,mHeight/2,radiu,mPaint);
mPaint.setColor(color_two);
canvas.drawCircle(mWidth/2+offset,mHeight/2,radiu,mPaint);
mPaint.setColor(color_three);
canvas.drawCircle(mWidth/2,mHeight/2-offset,radiu,mPaint);
mPaint.setColor(color_four);
canvas.drawCircle(mWidth/2,mHeight/2+offset,radiu,mPaint);
效果如图:
现在我们在静态小圆的基础上实现圆偏移的动态效果,定义偏移值,和偏移判断:
/*增还是减*/
private boolean isChanging = false;
/*变化的值*/
private int offsetChange;
/*四个球*/
mPaint.setColor(color_one);
canvas.drawCircle(mWidth/2-offsetChange,mHeight/2,radiu,mPaint);
mPaint.setColor(color_two);
canvas.drawCircle(mWidth/2+offsetChange,mHeight/2,radiu,mPaint);
mPaint.setColor(color_three);
canvas.drawCircle(mWidth/2,mHeight/2-offsetChange,radiu,mPaint);
mPaint.setColor(color_four);
canvas.drawCircle(mWidth/2,mHeight/2+offsetChange,radiu,mPaint);
if(isChanging){//递减
if(offsetChange > offset){
offsetChange --;
}else{
isChanging = false;
}
}else{//递加
if(offsetChange < offset + 30){
offsetChange ++;
}else{
isChanging = true;
}
}
postInvalidateDelayed(30);
偏移变化范围定为30,判断递增,递减,将小球的偏移值换成变化中的偏移值。此时就实现了小球动态远离/靠近的效果,没有动态图,就不贴了。
下面我们在添加画布旋转的效果,这里设置一个变化比例:
/*旋转的比例值*/
private int percent = 0;
这里我们2度一叠加:
percent+=2;
canvas.rotate(percent,mWidth/2,mHeight/2);
最终实现了效果,在linux系统动态效果图不好搞,只能上个静态图,后面会附上源码:
附上View的完整代码:
public class MyView extends View {
/*小圆半径*/
private int radiu;
/*四个球颜色值*/
private int color_one;
private int color_two;
private int color_three;
private int color_four;
/*偏移中心轴距离*/
private int offset;
//绘图工具
private Paint mPaint;
//View的宽高
private int mWidth,mHeight;
/*增还是减*/
private boolean isChanging = false;
/*变化的值*/
private int offsetChange;
/*旋转的比例值*/
private int percent = 0;
public MyView(Context context) {
this(context,null);
}
public MyView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.MyViewAttrs,defStyleAttr,0);
radiu = ta.getInt(R.styleable.MyViewAttrs_radiu,30);
color_one = ta.getColor(R.styleable.MyViewAttrs_color_one, Color.BLACK);
color_two = ta.getColor(R.styleable.MyViewAttrs_color_two, Color.BLACK);
color_three = ta.getColor(R.styleable.MyViewAttrs_color_three, Color.BLACK);
color_four = ta.getColor(R.styleable.MyViewAttrs_color_four, Color.BLACK);
offset = ta.getInt(R.styleable.MyViewAttrs_offset,50);
ta.recycle();
mPaint = new Paint();
mPaint.setStrokeWidth(3);
mPaint.setAntiAlias(true);
offsetChange = offset;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if(widthMode == MeasureSpec.EXACTLY){
mWidth = widthSize;
}else{
mWidth = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,400,getResources().getDisplayMetrics());
}
if(heightMode == MeasureSpec.EXACTLY){
mHeight = heightSize;
}else{
mHeight = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,400,getResources().getDisplayMetrics());
}
setMeasuredDimension(mWidth,mHeight);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
percent+=2;
canvas.rotate(percent,mWidth/2,mHeight/2);
/*四个球*/
mPaint.setColor(color_one);
canvas.drawCircle(mWidth/2-offsetChange,mHeight/2,radiu,mPaint);
mPaint.setColor(color_two);
canvas.drawCircle(mWidth/2+offsetChange,mHeight/2,radiu,mPaint);
mPaint.setColor(color_three);
canvas.drawCircle(mWidth/2,mHeight/2-offsetChange,radiu,mPaint);
mPaint.setColor(color_four);
canvas.drawCircle(mWidth/2,mHeight/2+offsetChange,radiu,mPaint);
if(isChanging){//递减
if(offsetChange > offset){
offsetChange --;
}else{
isChanging = false;
}
}else{//递加
if(offsetChange < offset + 30){
offsetChange ++;
}else{
isChanging = true;
}
}
postInvalidateDelayed(40);
}
}
源码:
csdn地址:http://download.csdn.net/detail/liujibin1836591303/9723215