http://chroya.iteye.com/blog/924577
快三个月了没写博客了,因为工作调动,很多经验、心得都没有时间记录下来。现在时间稍微充裕了点,我会尽量抽时间将之前想写而没写的东西补上。进入正题。
1. packagechroya.demo.magnifier;
2.
3. importandroid.content.Context;
4. importandroid.graphics.Bitmap;
5. importandroid.graphics.BitmapFactory;
6. importandroid.graphics.BitmapShader;
7. importandroid.graphics.Canvas;
8. importandroid.graphics.Matrix;
9. importandroid.graphics.Shader.TileMode;
10. importandroid.graphics.drawable.ShapeDrawable;
11. importandroid.graphics.drawable.shapes.OvalShape;
12. importandroid.view.MotionEvent;
13. importandroid.view.View;
14.
15.
16. publicclassShaderView extendsView{
17. privateBitmap bitmap;
18. privateShapeDrawable drawable;
19. //放大镜的半径
20. privatestaticfinalintRADIUS = 80;
21. //放大倍数
22. privatestaticfinalintFACTOR = 3;
23. privateMatrix matrix = newMatrix();
24.
25. publicShaderView(Context context) {
26. super(context);
27. Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.show);
28. bitmap = bmp;
29. BitmapShader shader = newBitmapShader(
30. Bitmap.createScaledBitmap(bmp, bmp.getWidth()*FACTOR,
31. bmp.getHeight()*FACTOR, true), TileMode.CLAMP, TileMode.CLAMP);
32. //圆形的drawable
33. drawable = newShapeDrawable(newOvalShape());
34. drawable.getPaint().setShader(shader);
35. drawable.setBounds(0, 0, RADIUS*2, RADIUS*2);
36. }
37.
38. @Override
39. publicbooleanonTouchEvent(MotionEvent event) {
40. finalintx = (int) event.getX();
41. finalinty = (int) event.getY();
42. //这个位置表示的是,画shader的起始位置
43. matrix.setTranslate(RADIUS-x*FACTOR, RADIUS-y*FACTOR);
44. drawable.getPaint().getShader().setLocalMatrix(matrix);
45. //bounds,就是那个圆的外切矩形
46. drawable.setBounds(x-RADIUS, y-RADIUS, x+RADIUS, y+RADIUS);
47. invalidate();
48. returntrue;
49. }
50.
51. @Override
52. publicvoidonDraw(Canvas canvas) {
53. super.onDraw(canvas);
54. canvas.drawBitmap(bitmap, 0, 0, null);
55. drawable.draw(canvas);
56. }
57. }
基本原理就是使用ShapeDrawable构造一个圆形的drawable,然后它的paint的shader设置为将要放大的图片,然后就是简单的位置移动问题了。放大镜的半径和放大倍数都可以在代码里面修改,代码都有注释,应该很好理解了。
不过,一个问题如果只有一种解决方法的话,那未免有点令人沮丧,想玩点另类的都不行。
玩程序就得玩出个性,玩出激情。哈哈,废话太多,切回正题。
1. packagechroya.demo.magnifier;
2.
3. importandroid.content.Context;
4. importandroid.graphics.Bitmap;
5. importandroid.graphics.BitmapFactory;
6. importandroid.graphics.Canvas;
7. importandroid.graphics.Matrix;
8. importandroid.graphics.Path;
9. importandroid.graphics.Path.Direction;
10. importandroid.view.MotionEvent;
11. importandroid.view.View;
12.
13.
14. publicclassPathView extendsView{
15. privatePath mPath = newPath();
16. privateMatrix matrix = newMatrix();
17. privateBitmap bitmap;
18. //放大镜的半径
19. privatestaticfinalintRADIUS = 80;
20. //放大倍数
21. privatestaticfinalintFACTOR = 2;
22. privateintmCurrentX, mCurrentY;
23.
24. publicPathView(Context context) {
25. super(context);
26. mPath.addCircle(RADIUS, RADIUS, RADIUS, Direction.CW);
27. matrix.setScale(FACTOR, FACTOR);
28.
29. bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.show);
30. }
31.
32. @Override
33. publicbooleanonTouchEvent(MotionEvent event) {
34. mCurrentX = (int) event.getX();
35. mCurrentY = (int) event.getY();
36.
37. invalidate();
38. returntrue;
39. }
40.
41. @Override
42. publicvoidonDraw(Canvas canvas) {
43. super.onDraw(canvas);
44. //底图
45. canvas.drawBitmap(bitmap, 0, 0, null);
46. //剪切
47. canvas.translate(mCurrentX - RADIUS, mCurrentY - RADIUS);
48. canvas.clipPath(mPath);
49. //画放大后的图
50. canvas.translate(RADIUS-mCurrentX*FACTOR, RADIUS-mCurrentY*FACTOR);
51. canvas.drawBitmap(bitmap, matrix, null);
52. }
53. }
貌似还缺点什么,是吧? 嘿嘿,就是放大镜外面缺个框。那玩意,我没资源,所以懒得弄了,有兴趣的自己加吧。