欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android放大镜的实现代码

程序员文章站 2022-06-29 09:37:23
*个月了没写博客了,因为工作调动,很多经验、心得都没有时间记录下来。现在时间稍微充裕了点,我会尽量抽时间将之前想写而没写的东西补上。进入正题。去年某个时候,我偶然看到一篇...

*个月了没写博客了,因为工作调动,很多经验、心得都没有时间记录下来。现在时间稍微充裕了点,我会尽量抽时间将之前想写而没写的东西补上。进入正题。
去年某个时候,我偶然看到一篇文章,讲android里面放大镜的实现。文章很乱,没有格式,基本上属于看不下去的那种。虽然体裁很有意思,但是我也没有足够的内力把它看完。不过看到一句关键的话,说是使用带圆形的drawable。这句话就够了,他下面写的一堆东西我也懒得看,于是就自己开始尝试,然后就做出来了。现在代码贴出来分享。
java代码

复制代码 代码如下:

package chroya.demo.magnifier;

import android.content.context;
import android.graphics.bitmap;
import android.graphics.bitmapfactory;
import android.graphics.bitmapshader;
import android.graphics.canvas;
import android.graphics.matrix;
import android.graphics.shader.tilemode;
import android.graphics.drawable.shapedrawable;
import android.graphics.drawable.shapes.ovalshape;
import android.view.motionevent;
import android.view.view;

/**
 * 放大镜实现方式1
 * @author chroya
 *
 */
public class shaderview extends view{
 private bitmap bitmap;
 private shapedrawable drawable;
 //放大镜的半径
 private static final int radius = 80;
 //放大倍数
 private static final int factor = 3;
 private matrix matrix = new matrix();

 public shaderview(context context) {
  super(context);
  bitmap bmp = bitmapfactory.decoderesource(getresources(), r.drawable.show);
  bitmap = bmp;  
  bitmapshader shader = new bitmapshader(
    bitmap.createscaledbitmap(bmp, bmp.getwidth()*factor,
      bmp.getheight()*factor, true), tilemode.clamp, tilemode.clamp);
  //圆形的drawable
  drawable = new shapedrawable(new ovalshape());
  drawable.getpaint().setshader(shader);
  drawable.setbounds(0, 0, radius*2, radius*2);
 } 

 @override
 public boolean ontouchevent(motionevent event) {
  final int x = (int) event.getx();
  final int y = (int) event.gety();
  //这个位置表示的是,画shader的起始位置
  matrix.settranslate(radius-x*factor, radius-y*factor);
  drawable.getpaint().getshader().setlocalmatrix(matrix);
  //bounds,就是那个圆的外切矩形
  drawable.setbounds(x-radius, y-radius, x+radius, y+radius);
  invalidate();
  return true;
 }

 @override
 public void ondraw(canvas canvas) {
  super.ondraw(canvas);
  canvas.drawbitmap(bitmap, 0, 0, null);
  drawable.draw(canvas);
 }
}

基本原理就是使用shapedrawable构造一个圆形的drawable,然后它的paint的shader设置为将要放大的图片,然后就是简单的位置移动问题了。放大镜的半径和放大倍数都可以在代码里面修改,代码都有注释,应该很好理解了。

不过,一个问题如果只有一种解决方法的话,那未免有点令人沮丧,想玩点另类的都不行。
玩程序就得玩出个性,玩出激情。哈哈,废话太多,切回正题。

再来看看放大镜的另外一种实现吧 ^-^
java代码

复制代码 代码如下:

package chroya.demo.magnifier;

import android.content.context;
import android.graphics.bitmap;
import android.graphics.bitmapfactory;
import android.graphics.canvas;
import android.graphics.matrix;
import android.graphics.path;
import android.graphics.path.direction;
import android.view.motionevent;
import android.view.view;

/**
 * 放大镜实现方式2
 * @author chroya
 *
 */
public class pathview extends view{
 private path mpath = new path();
 private matrix matrix = new matrix();
 private bitmap bitmap;
 //放大镜的半径
 private static final int radius = 80;
 //放大倍数
 private static final int factor = 2;
 private int mcurrentx, mcurrenty;

 public pathview(context context) {
  super(context);
  mpath.addcircle(radius, radius, radius, direction.cw);
  matrix.setscale(factor, factor);

  bitmap = bitmapfactory.decoderesource(getresources(), r.drawable.show);
 } 

 @override
 public boolean ontouchevent(motionevent event) {
  mcurrentx = (int) event.getx();
  mcurrenty = (int) event.gety();

  invalidate();
  return true;
 }

 @override
 public void ondraw(canvas canvas) {
  super.ondraw(canvas);
  //底图
  canvas.drawbitmap(bitmap, 0, 0, null);
  //剪切
  canvas.translate(mcurrentx - radius, mcurrenty - radius);
  canvas.clippath(mpath); 
  //画放大后的图
  canvas.translate(radius-mcurrentx*factor, radius-mcurrenty*factor);
  canvas.drawbitmap(bitmap, matrix, null);  
 }
}


这里使用的是path类,将canvas剪切出一块圆形区域,在其上绘制放大的部分。
两种方式的效果都一样,如图:

Android放大镜的实现代码

放大两倍的效果。

Android放大镜的实现代码

放大三倍

貌似还缺点什么,是吧? 嘿嘿,就是放大镜外面缺个框。那玩意,我没资源,所以懒得弄了,有兴趣的自己加吧。