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 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!