Android 自定義動(dòng)畫 單個(gè)View平面位移以及一組View輪回旋轉(zhuǎn)(一)

最近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),上圖

循環(huán)轉(zhuǎ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>



CSDN看代碼比較清晰哦,點(diǎn)這里

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容