編輯:關於Android編程
本文實例講解的是如何畫一個滿滿圓形水波紋loadingview,這類效果應用場景很多,比如內存占用百分比之類的,分享給大家供大家參考,具體內容如下
效果圖如下:
預備的知識:
千萬不要被這個b的名字嚇到,不熟悉看到可能會認為很難記,其實 只要站在巨人的丁丁上 還是很簡單的。
好了 廢話不多說 ,跟我一步步來做一個炫酷的view吧。
首先給一些屬性,在構造器裡初始化(不要再ondraw new東西不要再ondraw new東西不要再ondraw new東西不要再ondraw new東西)
//繪制波紋 private Paint mWavePaint; private PorterDuffXfermode mMode = new PorterDuffXfermode(PorterDuff.Mode.XOR);//設置mode 為XOR //繪制圓 private Paint mCirclePaint; private Canvas mCanvas;//我們自己的畫布 private Bitmap mBitmap; private int mWidth; private int mHeight; public WaveLoadingView(Context context) { this(context,null); } public WaveLoadingView(Context context, AttributeSet attrs) { this(context, attrs,0); } public WaveLoadingView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mWavePaint = new Paint(); mWavePaint.setColor(Color.parseColor("#33b5e5")); mCirclePaint = new Paint(); mCirclePaint.setColor(Color.parseColor("#99cc00")); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthSize = MeasureSpec.getSize(widthMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); if (widthMode == MeasureSpec.EXACTLY) { mWidth = widthSize; } if (heightMode == MeasureSpec.EXACTLY) { mHeight = heightSize; } setMeasuredDimension(mWidth, mHeight); mBitmap = Bitmap.createBitmap(300,300, Bitmap.Config.ARGB_8888); //生成一個bitmap mCanvas = new Canvas(mBitmap);//講bitmp放在我們自己的畫布上,實際上mCanvas.draw的時候 改變的是這個bitmap對象 }
然後,我們給他繪制一點東西,用來介紹PorterDuffXfermode
@Override protected void onDraw(Canvas canvas) { mCanvas.drawCircle(100,100,50,mCirclePaint); mCanvas.drawRect(100,100,200,200,mWavePaint); canvas.drawBitmap(mBitmap,0,0,null); super.onDraw(canvas); }
嗯,可以看到 是我們現在自己的畫布上鋪了一個bitmap(這裡可以理解canvas為桌子 bitmap為畫紙,我們在bimap上畫畫), 然後在bitmap上畫了 一個圓,和一個矩形。最後把我們的mBitmap畫到系統的畫布上(顯示到屏幕上),得到了以下效果。
然後我們用setXfermode()方法給他設置一個mode,這裡設置XOR。
可以發現! 相交的地方消失了! 是不是很神奇。
在改一個mode 試試
private PorterDuffXfermode mMode = new PorterDuffXfermode(PorterDuff.Mode.DST_OVER);
可以看到 圓形跑到了矩形上面來。 然後巨人給我們總結各個模式如了下圖,這裡給一個說明dst為先畫的 src為後畫的:.
大家可以根據這個規律試一下。
現在,我們把圓和矩形重疊。模式去掉。
protected void onDraw(Canvas canvas) { //dst mCanvas.drawCircle(150,150,50,mCirclePaint); / mWavePaint.setXfermode(mMode); //src mCanvas.drawRect(100,100,200,200,mWavePaint); canvas.drawBitmap(mBitmap,0,0,null); super.onDraw(canvas); }
我的圓怎麼沒了。。 其實圓是被覆蓋掉了。 然後我們想實現一個效果,就是在圓的范圍內,顯示矩形的內容,該怎麼做呢。自己照著圖找找吧哈哈。
我們要實現的是一個圓形的水波紋那種loadingview。。首要就是實現這個水波紋。
這時候貝塞爾曲線就派上用場了。這裡采用三階貝塞爾, 不停地改變X 模擬水波效果。
if (x > 50) { isLeft = true; } else if (x < 0) { isLeft = false; } <span > </span>if (y > -50) { //大於-50是因為輔助點是50 為了讓他充滿整個屏幕 y--; } if (isLeft) { x = x - 1; } else { x = x + 1; } mPath.reset(); mPath.moveTo(0, y); mPath.cubicTo(100 + x*2, 50 + y, 100 + x*2, y-50, mWidth, y);//前兩個參數是輔助點 mPath.lineTo(mWidth, mHeight);//充滿整個畫布 mPath.lineTo(0, mHeight);//充滿整個畫布 mPath.close();
之後用mCanvas來繪制這個bitmap,要注意的是 繪制之前要清空mBitmap,不然path會重疊
mBitmap.eraseColor(Color.parseColor("#00000000")); //dst mCanvas.drawPath(mPath, mPaint); canvas.drawBitmap(mBitmap, 0, 0, null); postInvalidateDelayed(10);
哈,水波效果出來了。 接著想辦法讓他畫到一個圓形中。 首先繪制一個圓
mCanvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, mSRCPaint);
現在讓我們回到剛才的問題,如何在dst的范圍內繪制src呢。。。答案是。。SRC_IN 你找對了嗎。添加模式
//dst mCanvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 2, mSRCPaint); mPaint.setXfermode(mMode); //src mCanvas.drawPath(mPath, mPaint); canvas.drawBitmap(mBitmap, 0, 0, null);
是不是有點感覺了。如果不這樣做 就需要考慮好多問題。動態計算沿著圓弧x,y坐標 計算arcTo的范圍。
完善一下,添加一個percent來代表進度,讓y來根據percent動態改變
y = (int) ((1-mPercent /100f) *mHeight);
添加setPercent方法
public void setPercent(int percent){ mPercent = percent; }
畫上百分比的文字。
String str = mPercent + "%"; float txtLength = mTextPaint.measureText(str); canvas.drawText(mPercent + "%", mWidth / 2-txtLength/2, mHeight / 2, mTextPaint);
然後配合seekBar,最後改改字體大小 畫筆透明度。 添加個背景圖 就成了效果圖上的效果。
是不是很有趣,大家可以動手實現一下!
最近因項目需求,需要在存儲卡查找文件,經測試發現部分手機掛載路徑查找不到,這裡分享一個有效的方法。 /** * 獲取所有存儲卡掛載路徑 * @return
本文實例講述了Android編程實現自定義PopupMenu樣式。分享給大家供大家參考,具體如下:PopupMenu是Android中一個十分輕量級的組件。與PopupW
直接附代碼:#import "MyView.h"#import // 行距const CGFloat kGlobalLineLeading = 5.0
所謂模式就是在某一情景下解決某個問題的固定解決方案。 所有的創建型模式都是用作對象的創建或實例化的解