一個簡單的Android軌跡動畫
本文實例為大家分享了Android軌跡動畫的具體代碼,供大家參考,具體內(nèi)容如下
二、需求描述
年中那會兒基友的公司給他了一張只有一條曲線的圖,想讓他按照曲線的軌跡動態(tài)展示整個曲線,然而基友忙于把妹,一個饅頭的代價收買了我,于是幫他寫了代碼。先看下實現(xiàn)效果
上原始圖(原始圖的軌跡曲線是白色的,其他部分是透明的,這里為了便于觀察,我將背景調(diào)為黑色)
三、分析實現(xiàn)
講道理,剛拿到這個圖片的時候我也有點懵逼,一個毫無規(guī)律的曲線很顯然不能通過簡單的方程式去描述點的具體位置,甚至想說設計直接給個動畫豈不美滋滋......
吐槽歸吐槽,需求還是要實現(xiàn)的,而且這個需求是有不少常見的方法可以進行實現(xiàn)的,比如上下兩層圖片保持一直,上層不斷從左到右將原圖縱向像素清除,然后將設計給的圖片也按照從左到友的順去繪制上去。不過這種方法的可擴展性太差,底層的圖片發(fā)生改變(滑動、變色)上層也需要進行配合。
這里使用方法是:將圖片中有色像素在圖片上的位置按照比例映射到要繪制的View中。
比如,原圖大小是200*100,要去做展示的View的尺寸大小是450*300,某點在原圖中位于x100,y20的位置,那么它在view中的位置應該為225,60。也就是說將該點在途中的位置比上原圖對應尺寸然后在乘以View的尺寸即可。
軌跡的獲取可以通過獲取全部的像素點顏色,因為透明的必然不是軌跡,所以判斷Alpha值即可,又因為軌跡是一條線,當我們使用Path連點的時候為了盡量減少不必要點的連接,我這里通過平均值的方式將曲線的寬度降為1。
由于點的位置是按照尺寸比例計算的,所以無論要展示的圖片尺寸有多奇葩,都可以完美適配上去
四、實現(xiàn)代碼
public class TestView extends View implements ViewTreeObserver.OnGlobalLayoutListener{
private Paint paint = new Paint();
private Bitmap bitmap;
private int[]local;
boolean enter = false;
int count;
ViewTreeObserver observer;
Canvas canvas;
float lastX = 0;
float lastY = 0;
public TestView(Context context) {
super(context);
}
public TestView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
observer = this.getViewTreeObserver();
observer.addOnGlobalLayoutListener(this);
getImageFromAssetsFile("target.png");//讀取圖片
}
public TestView(Context context, AttributeSet attrs) {
super(context, attrs);
observer = this.getViewTreeObserver();
observer.addOnGlobalLayoutListener(this);
getImageFromAssetsFile("target.png");
}
private void getImageFromAssetsFile(String fileName) {
AssetManager am = getResources().getAssets();
try {
InputStream is = am.open(fileName);
bitmap = BitmapFactory.decodeStream(is);
is.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
private void filterColor(){
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int[]pixels = new int[w*h];
local = new int[w];//以原圖寬為單位,保存點在原圖Y軸上的位置
bitmap.getPixels(pixels,0,bitmap.getWidth(),0,0,bitmap.getWidth(),bitmap.getHeight());
for(int i = 0; i < w; i++){
int lenght = 0;
int total = 0;
for(int j = 0;j<h;j++){
if (bitmap.getPixel(i, j) !=0) {
lenght++;
total+=j;
}
}
System.out.println(lenght+"");
if(lenght<15||((float)i/(float) w)<0.85)
local[i] = total/lenght;
else
break;
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(enter) {
paint.setAntiAlias(true); //設置畫筆為無鋸齒
paint.setColor(Color.WHITE); //設置畫筆顏色
canvas.drawColor(Color.TRANSPARENT); //透明背景
paint.setStrokeWidth((float) 6.0); //線寬
paint.setStyle(Paint.Style.STROKE);
Path path = new Path();
path.moveTo(0, (((float) getMeasuredHeight()-25) / (float)bitmap.getHeight()) * (float) local[0]+7);
if (count <= bitmap.getWidth()) {
if(count<bitmap.getWidth())
count++;
for (int i = 1; i < count - 1; i++) {
if(local[i]>0) {
path.lineTo((getMeasuredWidth() / (float) bitmap.getWidth()) * (float) i, (((float) getMeasuredHeight()-25) / (float) bitmap.getHeight()) * (float) local[i]+7);
lastX = (getMeasuredWidth() / (float) bitmap.getWidth()) * (float) i;
lastY = (((float) getMeasuredHeight()-25 )/ (float) bitmap.getHeight()) * (float) local[i];
}
}
}
if(count<bitmap.getWidth())
postInvalidate();
else {
count = 0;
postInvalidate();
}
canvas.drawPath(path, paint);
paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(lastX, lastY+7, 7, paint);
// }
}else{
this.canvas = canvas;
}
}
@Override
public void onGlobalLayout() {
filterColor();
enter = true;
postInvalidate();
}
}
當然了,這個代碼也只是給基友交差用的,還有不少地方能做優(yōu)化,比如:將圖片讀取放在子線程、對圖片大小進行判斷避免OOM、大圖加載圖片壓縮。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持我們。
欄 目:Android
下一篇:Android倒計時控件 Splash界面5秒自動跳轉(zhuǎn)
本文標題:一個簡單的Android軌跡動畫
本文地址:http://www.jygsgssxh.com/a1/Android/9174.html
您可能感興趣的文章
- 01-10android實現(xiàn)簡單計算器功能
- 01-10Android 友盟第三方登錄與分享的實現(xiàn)代碼
- 01-10Emoji表情在Android JNI中的兼容性問題詳解
- 01-10android開發(fā)環(huán)境中SDK文件夾下的所需內(nèi)容詳解
- 01-10Android實現(xiàn)底部導航欄的主界面
- 01-10Android實現(xiàn)漸變啟動頁和帶有指示器的引導頁
- 01-10Android實現(xiàn)簡單手電筒功能
- 01-10android特賣列表倒計時卡頓問題的解決方法
- 01-10Android倒計時的開始與停止 剩余時分秒的展示
- 01-10一個簡單的Android圓弧刷新動畫


閱讀排行
本欄相關
- 01-10Android自定義View之繪制圓形頭像功能
- 01-10Android實現(xiàn)雙擊返回鍵退出應用實現(xiàn)方
- 01-10android實現(xiàn)簡單計算器功能
- 01-10android實現(xiàn)記住用戶名和密碼以及自動
- 01-10C++自定義API函數(shù)實現(xiàn)大數(shù)相乘算法
- 01-10Android 友盟第三方登錄與分享的實現(xiàn)代
- 01-10android實現(xiàn)指紋識別功能
- 01-10如何給Flutter界面切換實現(xiàn)點特效
- 01-10Android實現(xiàn)圓形漸變加載進度條
- 01-10Emoji表情在Android JNI中的兼容性問題詳
隨機閱讀
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 04-02jquery與jsp,用jquery
- 01-10C#中split用法實例總結(jié)
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-10SublimeText編譯C開發(fā)環(huán)境設置
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10delphi制作wav文件的方法


