Android自定義view系列 - 仿360內存清理效果
宗旨都是一樣,帶大家一起來研究自定義view的實現,與其不同的是本系列省去了簡單的坐標之類的講解,重點在實現思路,用簡潔明了的文章,來與大家一同一步步學習。
轉載請注明出處:http://blog.csdn.net/wingichoy/article/details/50500479
上一篇介紹了:神奇的貝塞爾曲線,這篇就來研究其應用。
我自己的學習方法是:學習了貝塞爾曲線之后,去研究他的規律,然后開始聯想有沒有見過類似的效果,最后自己去研究實現,在沒有遇到絕對困難的時候,獨立思考。只有遇到了絕對困難或者做出來效果之后,才去參考其他人的做法。
好了,廢話不多說了,來看看效果圖:

圖片是從360安全衛士apk里面解壓的。一張背景圖,一張小綠的圖片。
先定義一些屬性
private int mWidth;
private int mHeight;
//線的Y坐標
private int mLineY = 600;
//判斷是否畫線回彈
private boolean isDrawBack = false;
private int mBitmapX;
private int mBitmapY;
//飛行的百分比
private int mFlyPercent = 100;
//輔助點坐標 x坐標為線段中點,
Point supPoint = new Point(350, mLineY);首先來畫背景圖片 ,和小人,這里背景圖片大小不對,沒想到有什么好的方法,這里先寫死(求解決,求不打死)。
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), com.wingsofts.my360clean.R.drawable.mb);
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inJustDecodeBounds = true;
// BitmapFactory.decodeResource(getResources(), com.wingsofts.my360clean.R.drawable.t,opt);
// int bgWidth = opt.outWidth;
// int bgHeight = opt.outHeight;
//按線的長度縮放背景圖
// Log.e("wing",bgWidth + " " +scale+"");
opt.inSampleSize= 2;
// opt.outWidth = 500;
opt.inJustDecodeBounds = false;
Bitmap background =BitmapFactory.decodeResource(getResources(), com.wingsofts.my360clean.R.drawable.t,opt);
Paint p = new Paint();
p.setStyle(Paint.Style.STROKE);
p.setStrokeWidth(20);
Path path = new Path();
//坐標寫死微調。。。別打我
canvas.drawBitmap(background,100,mLineY - background.getHeight()+100,p);
Point endPoint = new Point(600, mLineY);然后畫兩個圈圈。
p.setColor(Color.GRAY);
canvas.drawCircle(100, endPoint.y, 10, p);
canvas.drawCircle(endPoint.x,endPoint.y,10,p);之后根據一個標記位 isDrawBack來判斷是否畫線反彈。這里默認是不反彈。
p.setColor(Color.YELLOW);
path.moveTo(100, mLineY);
path.quadTo(supPoint.x, supPoint.y, endPoint.x, endPoint.y);//繪制貝塞爾曲線,
canvas.drawPath(path, p);
canvas.drawPoint(supPoint.x, supPoint.y, p);
mBitmapX = supPoint.x - bitmap.getWidth() / 2;
mBitmapY = (supPoint.y -mLineY)/2 + mLineY- bitmap.getHeight();
canvas.drawBitmap(bitmap, mBitmapX, mBitmapY, p);注意上面bitmap的坐標計算,這里為了方便,貝塞爾曲線只畫中點的。#實際上是不會# 觀察輔助點坐標

猜測輔助點到切線點 和切線點到mLineY的距離相等,然后計算出bitmap所在的坐標,進行繪制。
然后來繪制下拉時候的樣子,重寫onTouchEvent,主要是改變輔助點坐標和bitmap坐標,在action_move改變坐標 最后通知重繪。重寫action_up來改變最重點的坐標, 改變isDrawBack標記位,通知階段為上彈階段。
知識補充:getX是相對view的坐標 getRawX是相對屏幕的坐標.
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
supPoint.x = (int) event.getX();
if(event.getY()>mLineY)
supPoint.y = (int) event.getY();
invalidate();
break;
case MotionEvent.ACTION_UP:
endX = (int) event.getX();
endY = (int) event.getY();
isDrawBack = true;
invalidate();
break;
}
return true;
}
if (isDrawBack) {
p.setColor(Color.YELLOW);
path.moveTo(100, mLineY);
path.quadTo(supPoint.x, mLineY + (supPoint.y - mLineY) * mFlyPercent / 100, endPoint.x, endPoint.y);
canvas.drawPath(path, p);
if(mFlyPercent >0) {
canvas.drawBitmap(bitmap, mBitmapX, mBitmapY * mFlyPercent/100, p);
mFlyPercent -=5;
postInvalidateDelayed(10);
}else {
mFlyPercent = 100;
isDrawBack = false;
}這樣,變結束了模仿360內存清理效果,對于x坐標的計算。。。日后再研究。
本項目地址:點擊打開鏈接
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!