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;
2.배경 그리 기(바둑판)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)(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);
효과 그림:4.애니메이션 을 위 한 준비 와 애니메이션
1.세 개의 보조 클래스 가 애니메이션 을 위 한 준비(매개 변 수 는 Android 공식 데모 모방)
주로 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>
자바 파일 에서 가 져 오기
/**
*
*/
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();
}
6.사용자 정의 속성 설정 후 실행 효과7.작은 변화,시각 적 효과 가 달라 집 니 다!
그리고 배경 설명 을 기다 리 는 애니메이션 과 같 지 않 습 니까?
소스 코드
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();
}
});
안 드 로 이 드 사용자 정의 view 의 바둑 애니메이션 효과 실현 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 안 드 로 이 드 사용자 정의 view 바둑 애니메이션 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.