編輯:關於Android編程
直接上效果圖
功能特色:
1、可以設置刮開後顯示文字或圖片
2、可以統計已刮開區域所占百分比
Demo下載地址:RubberDemo.rar
下面是源碼:
@SuppressLint("HandlerLeak") public class RubberView extends TextView { private static final int W = 480; private static final int H = 800; private static final int MV = 1; private static final int SW = 50; private static final int MC = 0xFFD6D6D6; private int mWidth; private int mHeight; private int mMaskColor; private int mStrokeWidth; private float mX; private float mY; private boolean mRun; private boolean caculate; private Path mPath; private Paint mPaint; private Paint mBitmapPaint; private Canvas mCanvas; private Bitmap mBitmap; private int[] mPixels; private Thread mThread; private onWipeListener mWipeListener; public RubberView(Context context) { super(context); init(context); } public RubberView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } private final void init(Context context) { mMaskColor = MC; mStrokeWidth = SW; mPath = new Path(); mBitmapPaint = new Paint(); mPaint = new Paint(); mPaint.setAntiAlias(true);// 抗鋸齒 mPaint.setDither(true);// 遞色 mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); // 前圓角 mPaint.setStrokeCap(Paint.Cap.ROUND); // 後圓角 mPaint.setStrokeWidth(mStrokeWidth); // 筆寬 mBitmap = Bitmap.createBitmap(W, H, Config.ARGB_8888); mCanvas = new Canvas(mBitmap); mCanvas.drawColor(mMaskColor); mRun = true; mThread = new Thread(mRunnable); mThread.start(); setGravity(Gravity.CENTER); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mCanvas.drawPath(mPath, mPaint); canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int w = MeasureSpec.getSize(widthMeasureSpec); int h = MeasureSpec.getSize(heightMeasureSpec); if (w > 0 && h > 0) { mWidth = w; mHeight = h; } } public void reset() { mPath.reset(); mCanvas.drawPaint(mPaint); mCanvas.drawColor(mMaskColor); invalidate(); } public void setOnWipeListener(onWipeListener listerer) { this.mWipeListener = listerer; } public void setStrokeWidth(int width) { this.mStrokeWidth = width; mPaint.setStrokeWidth(width); } public void setMaskColor(int color) { this.mMaskColor = color; reset(); } @Override public boolean onTouchEvent(MotionEvent event) { boolean invalidate = false; boolean consume = false; int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: consume = true; touchDown(event); break; case MotionEvent.ACTION_MOVE: consume = true; invalidate = touchMove(event); break; case MotionEvent.ACTION_UP: consume = true; touchUp(event); break; } if (invalidate) { invalidate(); } if (consume) { return true; } return super.onTouchEvent(event); } // 手指點下屏幕時調用 private void touchDown(MotionEvent event) { caculate = false; // 重置繪制路線,即隱藏之前繪制的軌跡 mPath.reset(); float x = event.getX(); float y = event.getY(); mX = x; mY = y; // mPath繪制的繪制起點 mPath.moveTo(x, y); } // 手指在屏幕上滑動時調用 private boolean touchMove(MotionEvent event) { caculate = false; final float x = event.getX(); final float y = event.getY(); final float previousX = mX; final float previousY = mY; // 設置貝塞爾曲線的操作點為起點和終點的一半 float cX = (x + previousX) / 2; float cY = (y + previousY) / 2; final float dx = Math.abs(x - previousX); final float dy = Math.abs(y - previousY); boolean move = false; if (dx >= MV || dy >= MV) { // 二次貝塞爾,實現平滑曲線;cX, cY為操作點 x,y為終點 mPath.quadTo(cX, cY, x, y); // 第二次執行時,第一次結束調用的坐標值將作為第二次調用的初始坐標值 mX = x; mY = y; move = true; } return move; } private void touchUp(MotionEvent event) { caculate = true; mRun = true; } private Runnable mRunnable = new Runnable() { @Override public void run() { while (mRun) { SystemClock.sleep(100); // 收到計算命令,立即開始計算 if (caculate) { caculate = false; int w = mWidth; int h = mHeight; float wipeArea = 0; float totalArea = w * h; // 計算耗時100毫秒左右 Bitmap bitmap = mBitmap; if (mPixels == null) { mPixels = new int[w * h]; } bitmap.getPixels(mPixels, 0, w, 0, 0, w, h); for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { int index = i + j * w; if (mPixels[index] == 0) { wipeArea++; } } } if (wipeArea > 0 && totalArea > 0) { int percent = (int) (wipeArea * 100 / totalArea); Message msg = mHandler.obtainMessage(); msg.what = 0x1; msg.arg1 = percent; mHandler.sendMessage(msg); } } } } }; private Handler mHandler = new Handler() { public void handleMessage(Message msg) { if (mWipeListener != null) { int percent = msg.arg1; mWipeListener.onWipe(percent); } }; }; public interface onWipeListener { public void onWipe(int percent); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); mRun = false; } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。
之前對線程也寫過幾篇文章,不過倒是沒有針對android,因為java與android在線程方面大部分還是相同,不過本篇我們要介紹的是android的專屬類Handler
在Android Support Library19.1版本中,Android工具小組引入了幾個很酷的注解類型,供開發者在工程中使用。Support Libr
一、網絡爬蟲的基本知識網絡爬蟲通過遍歷互聯網絡,把網絡中的相關網頁全部抓取過來,這體現了爬的概念。爬蟲如何遍歷網絡呢,互聯網可以看做是一張大圖,每個頁面看做其中的一個節點
其實清除緩存是有兩種的,一種是清除手機rom裡面的緩存,一種是清除手機sd卡裡面的緩存,我們今天主要講的就是第一種 ps:這裡來一個知識掃盲,就是手機裡面的rom和r