Android自定义view之围棋动画效果的实现

前言

废话不多说直接开始

老规矩,文章最后有源码

完成效果图

棋子加渐变色

棋子不加渐变色

一、测量

1.获取宽高

 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  super.onSizeChanged(w, h, oldw, oldh);
  mWidth = w;
  mHeight = h;
  useWidth = mWidth;
  if (mWidth > mHeight) {
   useWidth = mHeight;
  }
 }

2.定义测量最小长度

将布局分为10份。以minwidth的1,3,5,7,9的倍数为标准点。

minwidth = useWidth / 10;

二、绘制背景(棋盘)

1.初始化画笔

 mPaint = new Paint();  //创建画笔对象
  mPaint.setColor(Color.BLACK); //设置画笔颜色
  mPaint.setStyle(Paint.Style.FILL); //设置画笔模式为填充
  mPaint.setStrokeWidth(4f);  //设置画笔宽度为10px
  mPaint.setAntiAlias(true);  //设置抗锯齿
  mPaint.setAlpha(255);  //设置画笔透明度

2.画棋盘

 //细的X轴
  canvas.drawLine(minwidth, 3 * minwidth, 9 * minwidth, 3 * minwidth, mPaint);// 斜线
  canvas.drawLine(minwidth, 5 * minwidth, 9 * minwidth, 5 * minwidth, mPaint);// 斜线
  canvas.drawLine(minwidth, 7 * minwidth, 9 * minwidth, 7 * minwidth, mPaint);// 斜线
  //细的y轴
  canvas.drawLine(3 * minwidth, minwidth, 3 * minwidth, 9 * minwidth, mPaint);// 斜线
  canvas.drawLine(5 * minwidth, minwidth, 5 * minwidth, 9 * minwidth, mPaint);// 斜线
  canvas.drawLine(7 * minwidth, minwidth, 7 * minwidth, 9 * minwidth, mPaint);// 斜线
  mPaint.setStrokeWidth(8f);
  //粗的X轴(边框)
  canvas.drawLine(minwidth, minwidth, 9 * minwidth, minwidth, mPaint);// 斜线
  canvas.drawLine(minwidth, 9 * minwidth, 9 * minwidth, 9 * minwidth, mPaint);// 斜线
  //粗的y轴(边框)
  canvas.drawLine(minwidth, minwidth, minwidth, 9 * minwidth, mPaint);// 斜线
  canvas.drawLine(9 * minwidth, minwidth, 9 * minwidth, 9 * minwidth, mPaint);// 斜线

绘制完后,发现有点小瑕疵
效果图:

3.补棋盘瑕疵

canvas.drawPoint(minwidth, minwidth, mPaint);
  canvas.drawPoint(9 * minwidth, minwidth, mPaint);
  canvas.drawPoint(minwidth, 9 * minwidth, mPaint);
  canvas.drawPoint(9 * minwidth, 9 * minwidth, mPaint);

效果图:

三.画个不可改变的棋子(以便于了解动画移动位置)

位置比例
(3,3)(3,5)(3,7)
(5,3)(5,5)(5,7)
(7,3)(7,5)(7,7)

 //画围棋
  canvas.drawCircle(3*minwidth, 3*minwidth, useWidth/16, mPaint);
  canvas.drawCircle(3*minwidth, 7*minwidth, useWidth/16, mPaint);
  canvas.drawCircle(5*minwidth, 5*minwidth, useWidth/16, mPaint);
  canvas.drawCircle(7*minwidth, 3*minwidth, useWidth/16, mPaint);
  canvas.drawCircle(7*minwidth, 7*minwidth, useWidth/16, mPaint);
  mPaint.setColor(rightcolor);
  canvas.drawCircle(3*minwidth, 5*minwidth, useWidth/16, mPaint);
  canvas.drawCircle(5*minwidth, 3*minwidth, useWidth/16, mPaint);
  canvas.drawCircle(5*minwidth, 7*minwidth, useWidth/16, mPaint);
  canvas.drawCircle(7*minwidth, 5*minwidth, useWidth/16, mPaint);

效果图:

四.为动画开始做准备以及动画

1.三个辅助类为动画做准备(参数模仿Android官方Demo)

主要为get set构造,代码会贴到最后

2.自定义该接口实例来控制动画的更新计算表达式

public class XYEvaluator implements TypeEvaluator {
 public Object evaluate(float fraction, Object startValue, Object endValue) {
  XYHolder startXY = (XYHolder) startValue;
  XYHolder endXY = (XYHolder) endValue;
  return new XYHolder(startXY.getX() + fraction * (endXY.getX() - startXY.getX()),
    startXY.getY() + fraction * (endXY.getY() - startXY.getY()));
 }
}

3.棋子的创建

private ShapeHolder createBall(float x, float y, int color) {
  OvalShape circle = new OvalShape();
  circle.resize(useWidth / 8f, useWidth / 8f);
  ShapeDrawable drawable = new ShapeDrawable(circle);
  ShapeHolder shapeHolder = new ShapeHolder(drawable);
  shapeHolder.setX(x - useWidth / 16f);
  shapeHolder.setY(y - useWidth / 16f);
  Paint paint = drawable.getPaint();
  paint.setColor(color);
  return shapeHolder;
 }

4.动画的创建

 private void createAnimation() {
  if (bounceAnim == null) {
   XYHolder lstartXY = new XYHolder(3 * minwidth - useWidth / 16f, 3 * minwidth - useWidth / 16f);
   XYHolder processXY = new XYHolder(7 * minwidth - useWidth / 16f, 3 * minwidth - useWidth / 16f);
   XYHolder lendXY = new XYHolder(7 * minwidth - useWidth / 16f, 7 * minwidth - useWidth / 16f);
   bounceAnim = ObjectAnimator.ofObject(ballHolder, "xY",
     new XYEvaluator(), lstartXY, processXY, lendXY, lstartXY);
   bounceAnim.setDuration(animaltime);
   bounceAnim.setRepeatCount(ObjectAnimator.INFINITE);
   bounceAnim.setRepeatMode(ObjectAnimator.RESTART);
   bounceAnim.addUpdateListener(this);
  }
  if (bounceAnim1 == null) {
   XYHolder lstartXY = new XYHolder(7 * minwidth - useWidth / 16f, 7 * minwidth - useWidth / 16f);
   XYHolder processXY = new XYHolder(3 * minwidth - useWidth / 16f, 7 * minwidth - useWidth / 16f);
   XYHolder lendXY = new XYHolder(3 * minwidth - useWidth / 16f, 3 * minwidth - useWidth / 16f);
   bounceAnim1 = ObjectAnimator.ofObject(ballHolder1, "xY",
     new XYEvaluator(), lstartXY, processXY, lendXY, lstartXY);
   bounceAnim1.setDuration(animaltime);
   bounceAnim1.setRepeatCount(ObjectAnimator.INFINITE);
   bounceAnim1.setRepeatMode(ObjectAnimator.RESTART);
   bounceAnim1.addUpdateListener(this);
  }
 }

5.两个动画的同步执行

AnimatorSet animatorSet = new AnimatorSet();
  animatorSet.play(bounceAnim).with(bounceAnim1);
  animatorSet.start();

6.效果图

视觉效果:感觉白子不太明显

7.解决第6步问题

在棋子的创建方法中添加渐变色

 RadialGradient gradient = new RadialGradient(useWidth / 16f, useWidth / 16f,
    useWidth / 8f, color, Color.GRAY, Shader.TileMode.CLAMP);
  paint.setShader(gradient);
  shapeHolder.setPaint(paint);

效果图:

五.自定义属性

attrs文件:

 <declare-styleable name="WeiqiView">
<!--  黑子颜色-->
  <attr name="leftscolor" format="reference|color"/>
<!--  白子颜色-->
  <attr name="rightscolor" format="reference|color"/>
<!--  棋盘颜色-->
  <attr name="qipancolor" format="reference|color"/>
<!--  动画时间-->
  <attr name="animalstime" format="integer"/>
 </declare-styleable>

java文件中获取

 /**
  * 获取自定义属性
  */
 private void initCustomAttrs(Context context, AttributeSet attrs) {
  //获取自定义属性
  TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.WeiqiView);
  //获取颜色
  leftcolor = ta.getColor(R.styleable.WeiqiView_leftscolor, Color.BLACK);
  rightcolor = ta.getColor(R.styleable.WeiqiView_rightscolor, Color.WHITE);
  qipancolor = ta.getColor(R.styleable.WeiqiView_qipancolor, Color.BLACK);
  //获取动画时间
  animaltime = ta.getInt(R.styleable.WeiqiView_animalstime, 2000);
  //回收
  ta.recycle();

 }

六.自定义属性设置后运行效果

七.小改变,视觉效果就不一样了!

然后,把背景注释,像不像那些等待动画?

八.源码

WeiqiView.java

public class WeiqiView extends View implements ValueAnimator.AnimatorUpdateListener {
 private Paint mPaint;
 private int mWidth;
 private int mHeight;
 private int useWidth, minwidth;
 private int leftcolor;
 private int rightcolor;
 private int qipancolor;
 private int animaltime;
 //画一个圆(棋子)
 ValueAnimator bounceAnim, bounceAnim1 = null;
 ShapeHolder ball, ball1 = null;
 QiziXYHolder ballHolder, ballHolder1 = null;

 @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
 public WeiqiView(Context context) {
  this(context, null);
 }

 @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
 public WeiqiView(Context context, @Nullable AttributeSet attrs) {
  this(context, attrs, 0);
 }

 @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
 public WeiqiView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
  this(context, attrs, defStyleAttr, 0);
  initCustomAttrs(context, attrs);
 }

 @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
 public WeiqiView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
  super(context, attrs, defStyleAttr, defStyleRes);

 }

 private void init() {
  initPaint();
 }

 /**
  * 获取自定义属性
  */
 private void initCustomAttrs(Context context, AttributeSet attrs) {
  //获取自定义属性。
  TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.WeiqiView);
  //获取颜色
  leftcolor = ta.getColor(R.styleable.WeiqiView_leftscolor, Color.BLACK);
  rightcolor = ta.getColor(R.styleable.WeiqiView_rightscolor, Color.WHITE);
  qipancolor = ta.getColor(R.styleable.WeiqiView_qipancolor, Color.BLACK);
  animaltime = ta.getInt(R.styleable.WeiqiView_animalstime, 2000);
  //回收
  ta.recycle();

 }

 /**
  * 初始化画笔
  */
 private void initPaint() {
  mPaint = new Paint();  //创建画笔对象
  mPaint.setColor(Color.BLACK); //设置画笔颜色
  mPaint.setStyle(Paint.Style.FILL); //设置画笔模式为填充
  mPaint.setStrokeWidth(4f);  //设置画笔宽度为10px
  mPaint.setAntiAlias(true);  //设置抗锯齿
  mPaint.setAlpha(255);  //设置画笔透明度
 }

 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  super.onSizeChanged(w, h, oldw, oldh);
  mWidth = w;
  mHeight = h;
  useWidth = mWidth;
  if (mWidth > mHeight) {
   useWidth = mHeight;
  }
 }

 @RequiresApi(api = Build.VERSION_CODES.KITKAT)
 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  init();
  minwidth = useWidth / 10;
  mPaint.setColor(qipancolor);
  if (ball == null) {
   ball = createBall(3 * minwidth, 3 * minwidth, leftcolor);
   ballHolder = new QiziXYHolder(ball);
  }
  if (ball1 == null) {
   ball1 = createBall(7 * minwidth, 7 * minwidth, rightcolor);
   ballHolder1 = new QiziXYHolder(ball1);
  }
  //细的X轴
  canvas.drawLine(minwidth, 3 * minwidth, 9 * minwidth, 3 * minwidth, mPaint);// 斜线
  canvas.drawLine(minwidth, 5 * minwidth, 9 * minwidth, 5 * minwidth, mPaint);// 斜线
  canvas.drawLine(minwidth, 7 * minwidth, 9 * minwidth, 7 * minwidth, mPaint);// 斜线
  //细的y轴
  canvas.drawLine(3 * minwidth, minwidth, 3 * minwidth, 9 * minwidth, mPaint);// 斜线
  canvas.drawLine(5 * minwidth, minwidth, 5 * minwidth, 9 * minwidth, mPaint);// 斜线
  canvas.drawLine(7 * minwidth, minwidth, 7 * minwidth, 9 * minwidth, mPaint);// 斜线
  mPaint.setStrokeWidth(8f);
  //粗的X轴(边框)
  canvas.drawLine(minwidth, minwidth, 9 * minwidth, minwidth, mPaint);// 斜线
  canvas.drawLine(minwidth, 9 * minwidth, 9 * minwidth, 9 * minwidth, mPaint);// 斜线
  //粗的y轴(边框)
  canvas.drawLine(minwidth, minwidth, minwidth, 9 * minwidth, mPaint);// 斜线
  canvas.drawLine(9 * minwidth, minwidth, 9 * minwidth, 9 * minwidth, mPaint);// 斜线
  //补瑕疵
  canvas.drawPoint(minwidth, minwidth, mPaint);
  canvas.drawPoint(9 * minwidth, minwidth, mPaint);
  canvas.drawPoint(minwidth, 9 * minwidth, mPaint);
  canvas.drawPoint(9 * minwidth, 9 * minwidth, mPaint);
//  //画围棋
//  canvas.drawCircle(3*minwidth, 3*minwidth, useWidth/16, mPaint);
//  canvas.drawCircle(3*minwidth, 7*minwidth, useWidth/16, mPaint);
//  canvas.drawCircle(5*minwidth, 5*minwidth, useWidth/16, mPaint);
//  canvas.drawCircle(7*minwidth, 3*minwidth, useWidth/16, mPaint);
//  canvas.drawCircle(7*minwidth, 7*minwidth, useWidth/16, mPaint);
//  mPaint.setColor(rightcolor);
//  canvas.drawCircle(3*minwidth, 5*minwidth, useWidth/16, mPaint);
//  canvas.drawCircle(5*minwidth, 3*minwidth, useWidth/16, mPaint);
//  canvas.drawCircle(5*minwidth, 7*minwidth, useWidth/16, mPaint);
//  canvas.drawCircle(7*minwidth, 5*minwidth, useWidth/16, mPaint);

  canvas.save();
  canvas.translate(ball.getX(), ball.getY());
  ball.getShape().draw(canvas);
  canvas.restore();

  canvas.save();
  canvas.translate(ball1.getX(), ball1.getY());
  ball1.getShape().draw(canvas);
  canvas.restore();
 }

 private ShapeHolder createBall(float x, float y, int color) {
  OvalShape circle = new OvalShape();
  circle.resize(useWidth / 8f, useWidth / 8f);
  ShapeDrawable drawable = new ShapeDrawable(circle);
  ShapeHolder shapeHolder = new ShapeHolder(drawable);
  shapeHolder.setX(x - useWidth / 16f);
  shapeHolder.setY(y - useWidth / 16f);
  Paint paint = drawable.getPaint();
  paint.setColor(color);
  RadialGradient gradient = new RadialGradient(useWidth / 16f, useWidth / 16f,
    useWidth / 8f, color, Color.GRAY, Shader.TileMode.CLAMP);
  paint.setShader(gradient);
  shapeHolder.setPaint(paint);
  return shapeHolder;
 }

 private void createAnimation() {
  if (bounceAnim == null) {
   XYHolder lstartXY = new XYHolder(3 * minwidth - useWidth / 16f, 3 * minwidth - useWidth / 16f);
   XYHolder processXY = new XYHolder(7 * minwidth - useWidth / 16f, 3 * minwidth - useWidth / 16f);
   XYHolder lendXY = new XYHolder(7 * minwidth - useWidth / 16f, 7 * minwidth - useWidth / 16f);
   bounceAnim = ObjectAnimator.ofObject(ballHolder, "xY",
     new XYEvaluator(), lstartXY, processXY, lendXY, lstartXY);
   bounceAnim.setDuration(animaltime);
   bounceAnim.setRepeatCount(ObjectAnimator.INFINITE);
   bounceAnim.setRepeatMode(ObjectAnimator.RESTART);
   bounceAnim.addUpdateListener(this);
  }
  if (bounceAnim1 == null) {
   XYHolder lstartXY = new XYHolder(7 * minwidth - useWidth / 16f, 7 * minwidth - useWidth / 16f);
   XYHolder processXY = new XYHolder(3 * minwidth - useWidth / 16f, 7 * minwidth - useWidth / 16f);
   XYHolder lendXY = new XYHolder(3 * minwidth - useWidth / 16f, 3 * minwidth - useWidth / 16f);
   bounceAnim1 = ObjectAnimator.ofObject(ballHolder1, "xY",
     new XYEvaluator(), lstartXY, processXY, lendXY, lstartXY);
   bounceAnim1.setDuration(animaltime);
   bounceAnim1.setRepeatCount(ObjectAnimator.INFINITE);
   bounceAnim1.setRepeatMode(ObjectAnimator.RESTART);
   bounceAnim1.addUpdateListener(this);
  }
 }

 public void startAnimation() {
  createAnimation();
  AnimatorSet animatorSet = new AnimatorSet();
  animatorSet.play(bounceAnim).with(bounceAnim1);
  animatorSet.start();
 }

 @Override
 public void onAnimationUpdate(ValueAnimator animation) {
  invalidate();
 }
}

QiziXYHolder.java

public class QiziXYHolder {

 private ShapeHolder mBall;

 public QiziXYHolder(ShapeHolder ball) {
  mBall = ball;
 }

 public void setXY(XYHolder xyHolder) {
  mBall.setX(xyHolder.getX());
  mBall.setY(xyHolder.getY());
 }

 public XYHolder getXY() {
  return new XYHolder(mBall.getX(), mBall.getY());
 }
}

ShapeHolder.java

public class ShapeHolder {
 private float x = 0, y = 0;
 private ShapeDrawable shape;
 private int color;
 private RadialGradient gradient;
 private float alpha = 1f;
 private Paint paint;

 public void setPaint(Paint value) {
  paint = value;
 }
 public Paint getPaint() {
  return paint;
 }

 public void setX(float value) {
  x = value;
 }
 public float getX() {
  return x;
 }
 public void setY(float value) {
  y = value;
 }
 public float getY() {
  return y;
 }
 public void setShape(ShapeDrawable value) {
  shape = value;
 }
 public ShapeDrawable getShape() {
  return shape;
 }
 public int getColor() {
  return color;
 }
 public void setColor(int value) {
  shape.getPaint().setColor(value);
  color = value;
 }
 public void setGradient(RadialGradient value) {
  gradient = value;
 }
 public RadialGradient getGradient() {
  return gradient;
 }

 public void setAlpha(float alpha) {
  this.alpha = alpha;
  shape.setAlpha((int)((alpha * 255f) + .5f));
 }

 public float getWidth() {
  return shape.getShape().getWidth();
 }
 public void setWidth(float width) {
  Shape s = shape.getShape();
  s.resize(width, s.getHeight());
 }

 public float getHeight() {
  return shape.getShape().getHeight();
 }
 public void setHeight(float height) {
  Shape s = shape.getShape();
  s.resize(s.getWidth(), height);
 }

 public ShapeHolder(ShapeDrawable s) {
  shape = s;
 }
}

XYEvaluator.java

public class XYEvaluator implements TypeEvaluator {
 public Object evaluate(float fraction, Object startValue, Object endValue) {
  XYHolder startXY = (XYHolder) startValue;
  XYHolder endXY = (XYHolder) endValue;
  return new XYHolder(startXY.getX() + fraction * (endXY.getX() - startXY.getX()),
    startXY.getY() + fraction * (endXY.getY() - startXY.getY()));
 }
}

XYHolder.java

public class XYHolder {
 private float mX;
 private float mY;

 public XYHolder(float x, float y) {
  mX = x;
  mY = y;
 }

 public float getX() {
  return mX;
 }

 public void setX(float x) {
  mX = x;
 }

 public float getY() {
  return mY;
 }

 public void setY(float y) {
  mY = y;
 }
}

attrs.xml

<resources>
 <declare-styleable name="WeiqiView">
<!--  黑子颜色-->
  <attr name="leftscolor" format="reference|color"/>
<!--  白子颜色-->
  <attr name="rightscolor" format="reference|color"/>
<!--  棋盘颜色-->
  <attr name="qipancolor" format="reference|color"/>
<!--  动画时间-->
  <attr name="animalstime" format="integer"/>
 </declare-styleable>
</resources>

布局调用

<com.shenzhen.jimeng.lookui.UI.WeiqiView
 android:layout_centerInParent="true"
 android:id="@+id/weiqi"
 android:layout_width="400dp"
 android:layout_height="400dp"/>

activity文件中开启动画

weiqi = (WeiqiView) findViewById(R.id.weiqi);
  weiqi.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    weiqi.startAnimation();
   }
  });

到此这篇关于Android自定义view之围棋动画效果的实现的文章就介绍到这了,更多相关Android自定义view围棋动画内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android自定义View实现水平带数字百分比进度条

    这个进度条可以反映真实进度,并且完成百分比的文字时随着进度增加而移动的,所在位置也恰好是真实完成的百分比位置,效果如下: 思路如下:第一部分是左侧的蓝色直线,代表已经完成的进度:第二部分是右侧灰色的直线,代表未完成的进度:第三部分是红色的百分比的数字百分比文本,显示当前确切的完成进度. 最关键的部分就是要确定百分比文本的确切位置,这里用了paint的getTextBounds方法,得到文本的宽高,然后再精确确定它的位置. view代码如下: public class NumberProgress

  • android简单自定义View实现五子棋

    本文实例为大家分享了android自定义View实现五子棋的具体代码,供大家参考,具体内容如下 先说一下吧,android的自定义View就是自己实现一个类去继承View,实现其中的方法,这里面我最感兴趣的就是onDraw方法了,因为你要的样式都要在这里面进实现,看一下效果图吧: 大概就是介个样子的,长得丑不要紧,能用就行,毕竟只是简单的了解一下嘛! *protected void onDraw(Canvas canvas) { super.onDraw(canvas); RectF rectF

  • Android自定义View实现拼图小游戏

    本文实例为大家分享了Android拼图小游戏的具体代码,供大家参考,具体内容如下 1.效果图: 运行时: 结束时: 2.PuzzleLayoutView: public class PuzzleLayoutView extends RelativeLayout implements View.OnClickListener { //表示将其切成2*2拼图(默认4块) private int mColumn = 2; //容器的内边距 private int mPadding; //每个块块的边距

  • Android自定义View实现课程表表格

    自己闲下来时间写的一个课表控件,使用的自定义LinearLayout,里面View都是用代码实现的,最终效果如下图,写的可能有问题希望多多指点 创建一个自定义LinearLayout 控件用来装载课程的信息和课程的周数,和节数大概的布局三这样的 根据上面的看来觉得总体布局我分了两个 上面的星期是一个 下面的节数和格子是一个  总体使用Vertical  而单独内部者使用了Horizontal布局  中间使用了两种布局线条 是这样的 /** * 横的分界线 * * @return */ priva

  • Android自定义View仿探探卡片滑动效果

    Android自定义View仿探探卡片滑动这种效果网上有很多人已经讲解了实现思路,大多都用的是RecyclerView来实现的,但是我们今天来换一种实现思路,只用一个自定义的ViewGroup来搞定这个实现. 下面我们先看一下实现的效果: 这个自定义View用法也很简单,首先从github上下载或者fork这个项目,在布局中添加: <com.liyafeng.view.swipecard.SwipeCardLayout android:id="@+id/scl_layout" a

  • Android自定义view之围棋动画效果的实现

    前言 废话不多说直接开始 老规矩,文章最后有源码 完成效果图 棋子加渐变色 棋子不加渐变色 一.测量 1.获取宽高 @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth = w; mHeight = h; useWidth = mWidth; if (mWidth > mHeight) { useWidth =

  • Android自定义View实现loading动画加载效果

    项目开发中对Loading的处理是比较常见的,安卓系统提供的不太美观,引入第三发又太麻烦,这时候自己定义View来实现这个效果,并且进行封装抽取给项目提供统一的loading样式是最好的解决方式了. 先自定义一个View,继承自LinearLayout,在Layout中,添加布局控件 /** * Created by xiedong on 2017/3/7. */ public class Loading_view extends LinearLayout { private Context m

  • Android 自定义view和属性动画实现充电进度条效果

    近期项目中需要使用到一种类似手机电池充电进度的动画效果,以前没学属性动画的时候,是用图片+定时器的方式来完成的,最近一直在学习动画这一块,再加上复习一下自定义view的相关知识点,所以打算用属性动画和自定义view的方式来完成这个功能,将它开源出来,供有需要的人了解一下相关的内容. 本次实现的功能类似下面的效果: 接下来便详细解析一下如何完成这个功能,了解其中的原理,这样就能举一反三,实现其他类似的动画效果了. 详细代码请看大屏幕 https://github.com/crazyandcoder

  • Android自定义VIew实现卫星菜单效果浅析

     一 概述: 最近一直致力于Android自定义VIew的学习,主要在看<android群英传>,还有CSDN博客鸿洋大神和wing大神的一些文章,写的很详细,自己心血来潮,学着写了个实现了类似卫星效果的一个自定义的View,分享到博客上,望各位指点一二.写的比较粗糙,见谅.(因为是在Linux系统下写的,效果图我直接用手机拍的,难看,大家讲究下就看个效果,勿喷). 先来看个效果图,有点不忍直视: 自定义VIew准备: (1)创建继承自View的类; (2)重写构造函数; (3)定义属性. (

  • Android自定义View实现波浪动画

    本文实例为大家分享了Android自定义View实现波浪动画的具体代码,供大家参考,具体内容如下 效果演示 代码调用与实现效果 xml中调用 <developer.shivam.waveview.Wave android:layout_width="match_parent" android:layout_height="match_parent" app:amplitude="100" app:quadrant="0.5&quo

  • Android自定义View实现数字雨效果的全过程

    目录 效果图 实现步骤 总结 效果图 在安卓中多种类型的动画,有帧动画.补间动画.属性动画,除此之外,使用自定义的View结合数学公式,就可以绘制出复杂的界面或者动画.这篇文章记录的是仿照黑客帝国的数字雨,来看看效果吧. 实现步骤 准备工作,常量的配置信息 // 文字的颜色值 final int DEFAULT_TEXT_COLOR = Color.argb(255, 0, 255, 70); // 文字大小 final int TEXT_SIZE = 24; // 普通画笔 Paint mPa

  • Android自定义View实现星星评分效果

    目录 前言 1.测量与图片的绘制 2.事件的交互与计算 3. 回调处理与自定义属性抽取 后记 前言 在前面的学习中,我们基本了解了一些 Canvas 的绘制,那么这一章我们一起复习一下图片的绘制几种方式,和事件的简单交互方式. 我们从易到难,作为基础的进阶控件,我们从最简单的交互开始,那就自定义一个星星评分的控件吧. 一个 App 必不可少的评论系统打分的控件,可以展示评分,可以点击评分,可以滑动评分.它的实现总体上可以分为以下的步骤: 强制测量大小为我们指定的大小 先绘制Drawable未评分

  • Android自定义View实现弹性小球效果

    照例先看效果图 自定义代码示例 public class BezierView extends View { Paint paint;//画笔 Path path;//路径 int radius = 50;//圆的半径 int time = 100;//计数时长 int index; int offsetIndex; float viewX, viewY;//图形中心点坐标 float width;//屏幕宽度 float partWidth;//屏幕宽度的1/4 int paddingLeft

  • Android自定义View实现折线图效果

    下面就是结果图(每种状态用一个表情图片表示): 一.主页面的布局文件如下: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height=&quo

  • Android自定义view渐变圆形动画

    本文实例为大家分享了Android自定义view渐变圆形动画的具体代码,供大家参考,具体内容如下 直接上效果图 自定义属性 attrs.xml文件 <resources> <declare-styleable name="ProgressRing"> <!--进度起始色--> <attr name="pr_progress_start_color" format="color" /> <!--

随机推荐