最近IOS的朋友寫了一個(gè)動(dòng)畫 問(wèn)我多長(zhǎng)時(shí)間能實(shí)現(xiàn),本著熱愛(ài)學(xué)習(xí)的精神,一下午搞出來(lái)一個(gè),,咳咳。。。
話不多說(shuō),先看第一個(gè)隨機(jī)運(yùn)動(dòng),上圖

這是一個(gè)比較初始的動(dòng)畫,主要是繪制一個(gè)小方塊View,并且改變這個(gè)View在畫布中的位置,然后進(jìn)行刷新Canvas來(lái)實(shí)現(xiàn)動(dòng)畫
關(guān)于代碼也是很簡(jiǎn)單,先創(chuàng)建一個(gè)been類去保存這個(gè)view的一些參數(shù)
<code>
/**
* @author: jjf
* @date: 2019/5/10
* @describe:View 參數(shù)
*/
public class BlockBeen {
? ? //初始View位置
? ? private int viewAddressX = 100;
? ? private int viewAddressY = 200;
? ? //View 大小
? ? private int viewWide = 100;
? ? private int viewHeight = 100;
? ? //畫view的畫筆倉(cāng)庫(kù)
? ? private? Paint viewPain ;
? ? //view倉(cāng)庫(kù)
? ? private RectF rectF;
? ? //地址狀態(tài) 0:第一排 1:牧默認(rèn)位置(中間一排) 2:下邊一排
? ? private int addressState;
? ? public int getAddressState() {
? ? ? ? return addressState;
? ? }
? ? public void setAddressState(int addressState) {
? ? ? ? this.addressState = addressState;
? ? }
? ? public int getViewAddressX() {
? ? ? ? return viewAddressX;
? ? }
? ? public void setViewAddressX(int viewAddressX) {
? ? ? ? this.viewAddressX = viewAddressX;
? ? }
? ? public int getViewAddressY() {
? ? ? ? return viewAddressY;
? ? }
? ? public void setViewAddressY(int viewAddressY) {
? ? ? ? this.viewAddressY = viewAddressY;
? ? }
? ? String TAG="MoveBlockView";
? ? public int getViewWide() {
? ? ? ? return viewWide;
? ? }
? ? public void setViewWide(int viewWide) {
? ? ? ? this.viewWide = viewWide;
? ? }
? ? public int getViewHeight() {
? ? ? ? return viewHeight;
? ? }
? ? public void setViewHeight(int viewHeight) {
? ? ? ? this.viewHeight = viewHeight;
? ? }
? ? public Paint getViewPain() {
? ? ? ? return viewPain;
? ? }
? ? public void setViewPain(Paint viewPain) {
? ? ? ? this.viewPain = viewPain;
? ? }
? ? public RectF getRectF() {
? ? ? ? return rectF;
? ? }
? ? public void setRectF(RectF rectF) {
? ? ? ? this.rectF = rectF;
? ? }
}
</code>
然后用這個(gè)模型,我們?nèi)ヌ畛湟唤M數(shù)據(jù),并把數(shù)據(jù)繪制出來(lái),請(qǐng)看大屏幕。。。
<code>
/**
? ? * 畫View
? ? *
? ? * @param canvas
? ? * @param position 第幾個(gè)view
? ? */
? ? public void drawBlock(Canvas canvas, int position) {//viewAddressY+ position * (viewWide+padding)+viewHeight
? ? ? ? BlockBeen blockBeen;
? ? ? ? if (position >= blockBeens.size()) {
? ? ? ? ? ? blockBeen = new BlockBeen();
? ? ? ? ? ? Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);//創(chuàng)建畫筆
? ? ? ? ? ? paint.setColor(getResources().getColor(R.color.colorPrimaryDark));//添加畫筆顏色
? ? ? ? ? ? blockBeen.setViewPain(paint);
? ? ? ? } else {
? ? ? ? ? ? blockBeen = blockBeens.get(position);
? ? ? ? }
? ? ? ? if (position == 0) {
? ? ? ? ? ? blockBeen.setViewAddressX(viewAddressX);
? ? ? ? ? ? blockBeen.setViewAddressY(viewAddressY - padding - blockBeen.getViewHeight());
? ? ? ? } else {
? ? ? ? ? ? blockBeen.setViewAddressX(viewAddressX + (position - 1) * (viewWide + padding));
? ? ? ? ? ? blockBeen.setViewAddressY(viewAddressY);
? ? ? ? }
? ? ? ? blockBeen.setViewWide(viewWide);
? ? ? ? blockBeen.setViewHeight(viewHeight);
? ? ? ? RectF rectF;
? ? ? ? if (blockBeen.getRectF() == null) {
? ? ? ? ? ? rectF = new RectF(blockBeen.getViewAddressX(), blockBeen.getViewAddressY(),
? ? ? ? ? ? ? ? ? ? blockBeen.getViewAddressX() + blockBeen.getViewWide(),
? ? ? ? ? ? ? ? ? ? blockBeen.getViewAddressY() + blockBeen.getViewHeight());//先畫一個(gè)矩形
? ? ? ? ? ? blockBeen.setRectF(rectF);
? ? ? ? } else {
? ? ? ? ? ? rectF = blockBeen.getRectF();
? ? ? ? ? ? rectF.set(blockBeens.get(position).getViewAddressX()
? ? ? ? ? ? ? ? ? ? , blockBeens.get(position).getViewAddressY(), blockBeens.get(position).getViewAddressX() + blockBeens.get(position).getViewWide()
? ? ? ? ? ? ? ? ? ? , blockBeens.get(position).getViewAddressY() + blockBeens.get(position).getViewHeight());
? ? ? ? }
? ? ? ? if (!blockBeens.contains(blockBeen)) {
? ? ? ? ? ? blockBeens.add(blockBeen);
? ? ? ? }
? ? ? ? canvas.drawRoundRect(rectF, 30, 30, blockBeen.getViewPain());//根據(jù)提供的矩形為四個(gè)角畫弧線,(其中的數(shù)字:第一個(gè)表示X軸方向大小,第二個(gè)Y軸方向大小??梢愿某善渌?,你可以自己體驗(yàn)),最后添加畫筆。
? ? ? ? //繪制View
? ? ? ? invalidate();
? ? }
</code>
好了,核心代碼已經(jīng)奉上,根據(jù)這個(gè)兩行代碼,大家應(yīng)該可以明白了這個(gè)視圖的繪制,關(guān)于行參中的position,是因?yàn)槲覟橄聜€(gè)動(dòng)畫準(zhǔn)備的,下個(gè)動(dòng)畫理論是可以無(wú)限增加個(gè)方塊去循環(huán)運(yùn)動(dòng),好了。最最最重要的環(huán)節(jié),就是讓這個(gè)方塊動(dòng)起來(lái):
<code>
/**
? ? * 移動(dòng)小方塊
? ? * @param position 第幾個(gè)View移動(dòng)
? ? * @param goX? 在X軸上移動(dòng)的幅度
? ? * @param goY? 在Y軸上移動(dòng)的幅度
? ? * @param canvas 畫布
? ? */
? ? private void moveTo(int position, int goX, int goY, Canvas canvas) {
? ? ? ? // check the borders, and set the direction if a border has reached
? ? ? ? if (blockBeens.get(position).getViewAddressX() > (parentWight - MAX_SIZE)) {
? ? ? ? ? ? goRight = false;
? ? ? ? }
? ? ? ? if (blockBeens.get(position).getViewAddressX() <= 0) {
? ? ? ? ? ? goRight = true;
? ? ? ? }
? ? ? ? if (blockBeens.get(position).getViewAddressY() > (parentHeight - MAX_SIZE)) {
? ? ? ? ? ? goDown = false;
? ? ? ? }
? ? ? ? if (blockBeens.get(position).getViewAddressY() <= 0) {
? ? ? ? ? ? goDown = true;
? ? ? ? }
? ? ? ? // move the x and y
? ? ? ? if (goRight) {
? ? ? ? ? ? blockBeens.get(position).setViewAddressX(blockBeens.get(position).getViewAddressX() + goX);
? ? ? ? } else {
? ? ? ? ? ? blockBeens.get(position).setViewAddressX(blockBeens.get(position).getViewAddressX() - goX);
? ? ? ? }
? ? ? ? if (goDown) {
? ? ? ? ? ? blockBeens.get(position).setViewAddressY(blockBeens.get(position).getViewAddressY() + goY);
? ? ? ? } else {
? ? ? ? ? ? blockBeens.get(position).setViewAddressY(blockBeens.get(position).getViewAddressY() - goY);
? ? ? ? }
? ? ? ? blockBeens.get(position).getRectF().set(blockBeens.get(position).getViewAddressX()
? ? ? ? ? ? ? ? , blockBeens.get(position).getViewAddressY(), blockBeens.get(position).getViewAddressX() + blockBeens.get(position).getViewWide()
? ? ? ? ? ? ? ? , blockBeens.get(position).getViewAddressY() + blockBeens.get(position).getViewHeight());
? ? ? ? canvas.drawRoundRect(blockBeens.get(position).getRectF(), 30, 30, blockBeens.get(position).getViewPain());
? ? ? ? invalidate();
? ? }
</code>
好了最后奉上這個(gè)代碼的引用部分,因?yàn)榱硪粋€(gè)動(dòng)畫?是在同一個(gè)類里面寫的,為了防止讀者混淆了,我把那個(gè)主要?jiǎng)赢嫹旁谙乱粋€(gè)博客中,當(dāng)然 完整的整篇代碼也會(huì)放在下一篇文章中。
引用部分
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
? ? xmlns:app="http://schemas.android.com/apk/res-auto"
? ? xmlns:tools="http://schemas.android.com/tools"
? ? android:layout_width="match_parent"
? ? android:layout_height="match_parent"
? ? android:background="#80000000"
? ? tools:context="com.jjf.blockmoveforcirclepath.MainActivity">
? ? <com.jjf.blockmoveforcirclepath.customview.MoveBlockView
? ? ? ? android:layout_width="match_parent"
? ? ? ? android:layout_height="match_parent" />
</android.support.constraint.ConstraintLayout>