編輯:關於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)函數進行繪制。
ImageLoader的簡單分析
剛接觸android的時候看到項目裡面用到了ImageLoader這個圖片緩存插件,當初抱著“知其然必要知其所以然”的想法還專門下載了它的源碼沒頭
實例講解Android中的AIDL內部進程通信接口使用
首先描述下我們想要實現的內容,我們希望在一個應用中通過點擊按鈕,去操作另一個進程中應用的音樂播放功能。如圖,我們點擊“播放”時,系統就會去遠程調用我們提供的一個servi
android裡shape與漸變色學習
先說下shape資源文件裡主要包括:邊角(corners),漸變色(gradrent),大小(size),邊距(padding) ,填充(solid),掃邊(stoke)
Android中制作自定義dialog對話框的實例分享
自定義dialog基礎版很多時候,我們在使用android sdk提供的alerdialog的時候,會因為你的系統的不同而產生不同的效果,就好比如你刷的是MIUI的系統,