編輯:關於Android編程
ViewGroup.java中繪制從dispatchDraw()開始,這裡的Canvas由ViewRootImpl.java中傳入,此時Canvas是屏幕大小的畫布。
@Override protected void dispatchDraw(Canvas canvas) { ... more |= drawChild(canvas, child, drawingTime); }
protected boolean drawChild(Canvas canvas, View child, long drawingTime) { return child.draw(canvas, this, drawingTime); }
boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) { ... int sx = 0; int sy = 0; if (!hasDisplayList) { computeScroll(); sx = mScrollX; sy = mScrollY; } final boolean hasNoCache = cache == null || hasDisplayList; final boolean offsetForScroll = cache == null && !hasDisplayList && layerType != LAYER_TYPE_HARDWARE; int restoreTo = -1; if (!useDisplayListProperties || transformToApply != null) { restoreTo = canvas.save(); } if (offsetForScroll) { canvas.translate(mLeft - sx, mTop - sy); } else { if (!useDisplayListProperties) { canvas.translate(mLeft, mTop); } if (scalingRequired) { if (useDisplayListProperties) { // TODO: Might not need this if we put everything inside the DL restoreTo = canvas.save(); } // mAttachInfo cannot be null, otherwise scalingRequired == false final float scale = 1.0f / mAttachInfo.mApplicationScale; canvas.scale(scale, scale); } } ... if (!layerRendered) { if (!hasDisplayList) { // Fast path for layouts with no backgrounds if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) { mPrivateFlags &= ~PFLAG_DIRTY_MASK; if (DBG_DRAW) { Xlog.d(VIEW_LOG_TAG, "view draw1 : calling dispatchDraw,this = " + this); } dispatchDraw(canvas); } else { if (DBG_DRAW) { Xlog.d(VIEW_LOG_TAG, "view draw1 : calling draw,this = " + this); } draw(canvas); } } else { mPrivateFlags &= ~PFLAG_DIRTY_MASK; ((HardwareCanvas) canvas).drawDisplayList(displayList, null, flags); ... }
上面這段代碼,有兩個需要指出的地方,一個就是canvas.translate()函數,這裡表明了ViewRootImpl傳進來的Canvas需要根據子視圖本身的布局大小進行裁減,也就是說屏幕上所有子視圖的canvas都只是一塊裁減後的大小的canvas,當然這也就是為什麼子視圖的canvas的坐標原點不是從屏幕左上角開始,而是它自身大小的左上角開始的原因。
第二個需要指出的是如果ViewGroup的子視圖仍然是ViewGroup,那麼它會回調dispatchDraw(canvas)進行分法,如果子視圖是View,那麼就調用View的draw(canvas)函數進行繪制。
剛接觸android的時候看到項目裡面用到了ImageLoader這個圖片緩存插件,當初抱著“知其然必要知其所以然”的想法還專門下載了它的源碼沒頭
首先描述下我們想要實現的內容,我們希望在一個應用中通過點擊按鈕,去操作另一個進程中應用的音樂播放功能。如圖,我們點擊“播放”時,系統就會去遠程調用我們提供的一個servi
先說下shape資源文件裡主要包括:邊角(corners),漸變色(gradrent),大小(size),邊距(padding) ,填充(solid),掃邊(stoke)
自定義dialog基礎版很多時候,我們在使用android sdk提供的alerdialog的時候,會因為你的系統的不同而產生不同的效果,就好比如你刷的是MIUI的系統,