您好,登錄后才能下訂單哦!
怎么在Android中使用view實(shí)現(xiàn)一個(gè)圍棋動(dòng)畫(huà)效果?相信很多沒(méi)有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。
@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; } }
將布局分為10份。以minwidth的1,3,5,7,9的倍數(shù)為標(biāo)準(zhǔn)點(diǎn)。
minwidth = useWidth / 10;
mPaint = new Paint(); //創(chuàng)建畫(huà)筆對(duì)象 mPaint.setColor(Color.BLACK); //設(shè)置畫(huà)筆顏色 mPaint.setStyle(Paint.Style.FILL); //設(shè)置畫(huà)筆模式為填充 mPaint.setStrokeWidth(4f); //設(shè)置畫(huà)筆寬度為10px mPaint.setAntiAlias(true); //設(shè)置抗鋸齒 mPaint.setAlpha(255); //設(shè)置畫(huà)筆透明度
//細(xì)的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);// 斜線 //細(xì)的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);// 斜線
繪制完后,發(fā)現(xiàn)有點(diǎn)小瑕疵
效果圖:
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)
//畫(huà)圍棋 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);
效果圖:
主要為get set構(gòu)造,代碼會(huì)貼到最后
2.自定義該接口實(shí)例來(lái)控制動(dòng)畫(huà)的更新計(jì)算表達(dá)式
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.棋子的創(chuàng)建
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.動(dòng)畫(huà)的創(chuàng)建
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.兩個(gè)動(dòng)畫(huà)的同步執(zhí)行
AnimatorSet animatorSet = new AnimatorSet(); animatorSet.play(bounceAnim).with(bounceAnim1); animatorSet.start();
6.效果圖
視覺(jué)效果:感覺(jué)白子不太明顯
7.解決第6步問(wèn)題
在棋子的創(chuàng)建方法中添加漸變色
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"/> <!-- 棋盤(pán)顏色--> <attr name="qipancolor" format="reference|color"/> <!-- 動(dòng)畫(huà)時(shí)間--> <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); //獲取動(dòng)畫(huà)時(shí)間 animaltime = ta.getInt(R.styleable.WeiqiView_animalstime, 2000); //回收 ta.recycle(); }
然后,把背景注釋?zhuān)癫幌衲切┑却齽?dòng)畫(huà)?
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; //畫(huà)一個(gè)圓(棋子) 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(); } /** * 初始化畫(huà)筆 */ private void initPaint() { mPaint = new Paint(); //創(chuàng)建畫(huà)筆對(duì)象 mPaint.setColor(Color.BLACK); //設(shè)置畫(huà)筆顏色 mPaint.setStyle(Paint.Style.FILL); //設(shè)置畫(huà)筆模式為填充 mPaint.setStrokeWidth(4f); //設(shè)置畫(huà)筆寬度為10px mPaint.setAntiAlias(true); //設(shè)置抗鋸齒 mPaint.setAlpha(255); //設(shè)置畫(huà)筆透明度 } @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ì)的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);// 斜線 //細(xì)的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);// 斜線 //補(bǔ)瑕疵 canvas.drawPoint(minwidth, minwidth, mPaint); canvas.drawPoint(9 * minwidth, minwidth, mPaint); canvas.drawPoint(minwidth, 9 * minwidth, mPaint); canvas.drawPoint(9 * minwidth, 9 * minwidth, mPaint); // //畫(huà)圍棋 // 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"/> <!-- 棋盤(pán)顏色--> <attr name="qipancolor" format="reference|color"/> <!-- 動(dòng)畫(huà)時(shí)間--> <attr name="animalstime" format="integer"/> </declare-styleable> </resources>
布局調(diào)用
<com.shenzhen.jimeng.lookui.UI.WeiqiView android:layout_centerInParent="true" android:id="@+id/weiqi" android:layout_width="400dp" android:layout_height="400dp"/>
activity文件中開(kāi)啟動(dòng)畫(huà)
weiqi = (WeiqiView) findViewById(R.id.weiqi); weiqi.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { weiqi.startAnimation(); } });
看完上述內(nèi)容,你們掌握怎么在Android中使用view實(shí)現(xiàn)一個(gè)圍棋動(dòng)畫(huà)效果的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。