概述

我相信很多用过英语应用的同学都看多一个放大镜的效果,就是选中一段文字后,会有一个放大镜,这个究竟怎么实现的呢,我们今天来分析分析。

源码分析

public class ShaderView extends View {
    private final Bitmap bitmap;
    private final ShapeDrawable drawable;
    // 放大镜的半径  

    private static final int RADIUS = 80;
    // 放大倍数  

    private static final int FACTOR = 3;
    private final Matrix matrix = new Matrix();  

    public ShaderView(Context context) {
        super(context);
        Bitmap bmp = BitmapFactory.decodeResource(getResources(),R.drawable.demo);
        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设置为将要放大的图片,然后就是简单的位置移动问题了。放大镜的半径和放大倍数都可以在代码里面修改,代码都有注释,应该很好理解了。
不过,一个问题如果只有一种解决方法的话,那未免有点令人沮丧,想玩点另类的都不行。玩程序就得玩出个性,玩出激情。哈哈,废话太多,切回正题。再来看看放大镜的另外一种实现吧
public class PathView extends View {
    private final Path mPath = new Path();
    private final Matrix matrix = new Matrix();
    private final 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.demo);
    }  

    @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放大镜效果实现的更多相关文章

  1. Android放大镜效果的简单实现

    package com.example.myapi.pictobig; import com.example.myapi.R; import android.content.Context; impo ...

  2. Android动画效果之自定义ViewGroup添加布局动画

    前言: 前面几篇文章介绍了补间动画.逐帧动画.属性动画,大部分都是针对View来实现的动画,那么该如何为了一个ViewGroup添加动画呢?今天结合自定义ViewGroup来学习一下布局动画.本文将通 ...

  3. Android动画效果之Property Animation进阶(属性动画)

    前言: 前面初步认识了Android的Property Animation(属性动画)Android动画效果之初识Property Animation(属性动画)(三),并且利用属性动画简单了补间动画 ...

  4. Android动画效果之初识Property Animation(属性动画)

    前言: 前面两篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画).Frame Animation(逐帧动画)Andr ...

  5. Android动画效果之Frame Animation(逐帧动画)

    前言: 上一篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画),今天来总结下Android的另外一种动画Frame ...

  6. Android动画效果之Tween Animation(补间动画)

    前言: 最近公司项目下个版本迭代里面设计了很多动画效果,在以往的项目中开发中也会经常用到动画,所以在公司下个版本迭代开始之前,抽空总结一下Android动画.今天主要总结Tween Animation ...

  7. 关于jQuery中实现放大镜效果

    1.1.1 摘要 相信大家都见过或使用过放大镜效果,甚至实现过该效果,它一般应用于放大查看商品图片,一些电商网站(例如:凡客,京东商城,阿里巴巴等)都有类似的图片查看效果. 在接下来的博文中,我们将向 ...

  8. 利用JS实现购物网站商品放大镜效果

    大家几乎都有在网上购物的经验,有的网站会有一个商品放大镜功能, 就是把鼠标移到图片上的时候,旁边会有另外一张大的图片展示,等同于 放大镜效果,那这样的效果怎样实现的呢,我把代码发给大家,请大家参考. ...

  9. 【JavaScript】放大镜效果

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

随机推荐

  1. Docker常见仓库MongoDB

    MongoDB 基本信息 MongoDB 是开源的 NoSQL 数据库实现. 该仓库提供了 MongoDB 2.2 ~ 2.7 各个版本的镜像. 使用方法 默认会在 27017 端口启动数据库. $ ...

  2. Nginx之(二)Nginx安装

    首先从官网上http://nginx.org/下载最新的stable version源码,当前最新版本为nginx-1.10.2.tar.gz. 2.1 configure 解压之后,会发现里面有一个 ...

  3. AWS EC2 CentOS release 6.5 部署zookeeper、kafka、dubbo

    AWS EC2 CentOS release 6.5 部署zookeeper.kafka.dubbo参考:http://blog.csdn.net/yizezhong/article/details/ ...

  4. Scroll Segmented Control(Swift)

    今天用了一个github上一个比较好用的Segmented Control但是发现不是我要效果,我需要支持scrollView.当栏目数量超过一屏幕,需要能够滑动. 由于联系作者没有回复,我就自己在其 ...

  5. postgresql 登录查看表定义

    su - postgres psql \connect database_name; \d table_name

  6. 安卓高级 Android图片缓存之初识Glide

    前言: 前面总结学习了图片的使用以及Lru算法,今天来学习一下比较优秀的图片缓存开源框架.技术本身就要不断的更迭,从最初的自己使用SoftReference实现自己的图片缓存,到后来做电商项目自己的实 ...

  7. 安卓高级2 swipeReferenceLayout 使用案例 和完善其自定义上拉

    swipeReferenceLayout 无法完成上来加载数据所以自定义了一个类 Activity.java package qianfeng.com.swipelayoutdemo; import ...

  8. Ruby 连接MySQL数据库

    使用Ruby连接数据库的过程还真的是坎坷,于是写点文字记录一下. 简介 Ruby简介 RubyGems简介 包管理之道 比较著名的包管理举例 细说gem 常用的命令 准备 驱动下载 dbi mysql ...

  9. Servlet - Listener、Filter、Decorator

    Servlet 标签 : Java与Web Listener-监听器 Listener为在Java Web中进行事件驱动编程提供了一整套事件类和监听器接口.Listener监听的事件源分为Servle ...

  10. 【Unity Shader】2D动态云彩

    写在前面 赶在年前写一篇文章.之前翻看2015年的SIGGRAPH Course(关于渲染的可以去selfshadow的博客里找到,很全)的时候看到了关于体积云的渲染.这个课程讲述了开发者为游戏< ...