【Android开发】范例2-实现放大镜效果

【Android开发】范例2-实现放大镜效果

利用之前学过的图形图像绘画技术和图片添加特效技术,我们来实现一个Android放大镜的简单应用。

最终效果如图

【Android开发】范例2-实现放大镜效果

具体实现:

用来显示自定义的绘图类的布局文件

res/layout/main.xml:

<?xml version="1.0" encoding="utf-8"?>  
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/frameLayout1"
    android:orientation="vertical"
    >
	
</FrameLayout>

打开MainActivity,在文件中创建名为MyView的内部类,继承android.view.View类,并添加构造方法和重写onDraw(Canvas canvas)方法,在里面进行作图:

MainActivity:

package com.example.test;  
  
import android.app.Activity;
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.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
  
public class MainActivity extends Activity {  


    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
      
      //获取布局文件中添加的帧布局管理器
        FrameLayout fl=(FrameLayout)findViewById(R.id.frameLayout1);
        //将自定义的MyView视图添加到帧布局
        fl.addView(new MyView(this));
	}
   
    public class MyView extends View{
    	private Bitmap bitmap;//源图像,也就是背景图像
    	private ShapeDrawable drawable;
    	private final int RADIUS=57;//放大镜的半径
    	private final int FACTOR=2;//放大倍数
    	private Matrix matrix=new Matrix();
    	private Bitmap bitmap_magnifiter;//放大镜位图
    	private int m_left=0;//放大镜的左边距
    	private int m_top=0;//放大镜的顶边距
    	
		public MyView(Context context) {
			super(context);
			
			//获取要显示的源图像
		    Bitmap bitmap_source=BitmapFactory.decodeResource(getResources(), R.drawable.backgroud);
		    bitmap=bitmap_source;
		    BitmapShader shader=new BitmapShader(Bitmap.createScaledBitmap(
		    		bitmap_source, bitmap_source.getWidth()*FACTOR, 
		    		bitmap_source.getHeight()*FACTOR, true),TileMode.CLAMP,
		    		TileMode.CLAMP);//创建BitmapShader对象
		    /* 注:Bitmap.createScaledBitmap() 方 法根据给定的 Bitmap 创建 一个新的,缩放后的 Bitmap。
		     * Shader.TileMode类型的参数包括CLAMP、MIRROR和REPEAT3个可选值,其中,CLAMP为使用
		     * 边界颜色来填充剩余的空间;MIRROR为采用镜像方式;REPEAT为采用重复方式*/
		   
		    //圆形的drawable
		    drawable=new ShapeDrawable(new OvalShape());
		    drawable.getPaint().setShader(shader);
		    drawable.setBounds(0, 0, RADIUS*2, RADIUS*2);//设置圆的外切矩形
		    bitmap_magnifiter=BitmapFactory.decodeResource(getResources(), 
		    		R.drawable.magnifiter);//获取放大镜图像
		    m_left=RADIUS-bitmap_magnifiter.getWidth()/2;//计算放大镜默认的左边距
		    m_top=RADIUS-bitmap_magnifiter.getHeight()/2;//计算放大镜默认的右边距
		}


		@Override
		protected void onDraw(Canvas canvas) {
			canvas.drawBitmap(bitmap, 0,0, null);//绘制背景图像
		    canvas.drawBitmap(bitmap_magnifiter, m_left, m_top,null);//绘制放大镜图像
		    drawable.draw(canvas);//绘制放大后的图像
			super.onDraw(canvas);
		}


		//重写onTouchEvent方法实现当用户触摸屏幕时,放大触摸点附近的图像
		@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);
			drawable.setBounds(x-RADIUS,y-RADIUS,x+RADIUS,y+RADIUS);//设置圆的外切矩形
			m_left=x-bitmap_magnifiter.getWidth()/2;//计算放大镜的左边距
		    m_top=y-bitmap_magnifiter.getHeight()/2;//计算放大镜的右边距
		    invalidate();//重绘画布
		    
			return true;
		}
    	
		
    }
}  

运行效果如开头图片显示效果一样,测试成功。

转载请注明出处:http://blog.csdn.net/acmman/article/details/45624465

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/109455.html原文链接:https://javaforall.net

(0)
上一篇 2021年9月6日 下午7:00
下一篇 2021年9月6日 下午7:00


相关推荐

  • vue支持es6_vue2转vue3

    vue支持es6_vue2转vue3转载:Vue2.0ES6语法降级ES5由于部分低版本的手机还不支持ES6语法,将会导致vue报错。综合了网上的各种办法,我的项目现在终于成功降级ES5.首先安装插件npminstall-Dbabel-preset-es2015babel-corebabel-preset-stage-2babel-loader编辑配置文件…

    2026年3月9日
    3
  • uWSGI详解_shell bash

    uWSGI详解_shell bashWSGI是什么?WSGI,全称 WebServerGatewayInterface,或者 PythonWebServerGatewayInterface,是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。自从WSGI被开发出来以后,许多其它语言中也出现了类似接口。WSGI 的官方定义是,thePythonWe

    2025年10月30日
    4
  • redis 消息队列 延时队列

    redis 消息队列 延时队列Springboot2 0 基于 Redis 快速实现消息队列 pub sub 功能 Springboot Redis 实现消息队列 生产者 消费者 发布订阅模式 SpringBoot 基于事件的 Redis 消息队列实现异步操作 redis 实现消息队列 Redis 发布订阅传对象消息队列 基于 Redisson SpringBoot 整合 Redis 延时队列的简单实现 基于有赞的设计 延时队列 基于 Redisson 实现的延时队列生成订单 30 分钟未支付 则自动取消 该怎么实现 Redis 实现关闭订单

    2026年3月18日
    1
  • pstack学习笔记

    pstack学习笔记################################################################################pstack学习笔记v0.12013.10.8*** 简介:pstack的功能是显示当前进程中函数的调用栈的关系,若是多线程的情况下,会显示各个      线程中函数调用的关系。 

    2025年11月16日
    4
  • 低压无功补偿电容柜浅谈

    低压无功补偿电容柜浅谈1.3、工作原理合上刀熔开关和断路器,无功功率补偿控制器根据进线柜电压和电流的相位差输出控制信号,控制交流接触器闭合和断开,从而控制电容器投入和退出。  2、电容器补偿柜的及其作用 2.1、电容器柜功能及其结构                外部结构             内部结构              2.2、电容器补偿柜的作用    电容补偿

    2022年5月30日
    66
  • Matlab griddata函数功能介绍

    Matlab griddata函数功能介绍转载▼标签: 杂谈 分类:matlab 功能数据格点格式(1)ZI=griddata(x,y,z,XI,YI)用二元函数z=f(x,y)的曲面拟合有不规则的数据向量x,y,z。griddata将返回曲面z在点(XI,YI)处的插值。曲面总是经过这些数据点(x,y,z)的。输入参量(XI,YI)通常是规则的格点(像用命令meshgrid生成的一样)。…

    2022年5月26日
    63

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号