UI calibration is one of the latest features comes into Hurdle. With this functionality, UEDs and developers are able to check whether the UI implementation is aligned with design spec. Color-picker and magnifier is one of the feature inside.
Obtain bitmap from Activity
The content to show inside MagnifierView is a crop from background Activity bitmap. To obtain a bitmap of the Activity:
Before implementing onDraw(), there are something to be prepared. First we have a content-bitmap and a mask-bitmap, both with the same size of the MagnifierView, say 130*130dp. The mask-bitmap is from a bitmap drawable which is a white-colored circle with transparent background.
Draw the magnifier
Whenever the magnifier is moved, calculate the part of activity-bitmap which should be shown inside, copy that area into content-bitmap, as the content-bitmap is much smaller than activity-bitmap, it is cropped. Then mask the content-bitmap against the mask-bitmap, which translate the shape of content-bitmap from rectanglar to circle.
Somebody may point out that rawY should be substract by the height of system notification bar. But in fact, the Activity window is actually drawn full-screen, the notification bar is an overlay at the top. The Activity window just leaves the area obstructed as transparent.
Please note that the parameters passed to Canvas.translate() are (-bmpLtX, -bmpLtY), instead of (bmpLtX, bmpLtY). I was quite confusing about this at the begining. Translation moves the base point (0, 0) of the Canvas to (-bmpLtX, -bmpLtY), say (-150, -200). When the activity-bitmap is then drawn to the canvas, the base point of the bitmap is actually drawn at view coordinator (-150, -200), which is out of the screen and will not displayed. So the point of bitmap (150, 200) is now drawn at view coordinator (0, 0), that exactly what I want.
Update window location
The MagnifierView is show atop of any Activity. It's manipulated directly by WindowManager.