通常在两种情况下人们会思变求新:一种是希望摆脱危机,另一种只是单纯地想要一些新鲜的改变,没有什么特别迫切的需要。在前者,发出期盼的人即不幸福也不富足,而后者幸福而富裕。(不明之事乃命运之域,确定之事乃法之所辖)

Android自定义控件今天要讲到的就是望远镜效果,那么什么是望远镜效果,我们不妨看看下方的动图,看完后,相信大家就有一定的认识了。

1.着色器

对于这种效果来说,其实实现起来挺简单的,但我们将会用到在三维软件中的着色器Shader,它是用来给空白图形上色的。用过PS的人,相信大家都知道里面有一个印章工具,印章的样式可以是图像,颜色,渐变色等。在Android里面,Shader的效果其实与他类似。

public Shader setShader(Shader shader)

上面是Shader的专用函数,也是画笔Paint中的函数,我们今天要用到的是BitmapShader,也即是图片来填充,它的基本用法如下:

public BitmapShader(Bitmap bitmap,TileMode tileX,TileMode tileY)

tileX用来指定当X轴超出单张图片大小时所使用的重复策略

tileY用来指定当Y轴超出单张图片大小时所使用的重复策略

而这两个值的取值有三种,分别是:

TileMode.CLAMP:用边缘色彩来填充多余空间,CLAMP就是以X轴填充X边缘颜色,以Y轴填充Y轴边缘颜色,而XY非图片相交区域以填充Y轴的颜色继续填充。(这里估计博主故意把猫右边缘填充了黑色,Y边缘填充了红色,框起来的地方是原图)

TileMode.REPEAT:重复原图像来填充多余空间,其实这个模式最好理解,就是复制粘贴,X不够的空白区域填充原图,Y不够的也用原图像填充。

TileMode.MIRROR:重复使用镜像模式的图像来填充多余空间,有可能有的小伙伴不懂MIRROR镜像模式,其实镜像模式就是想镜子一样翻转了图像,如下图所示:

2.望远镜效果实现

原理已经剖析清楚了,接着,我们就来实现开头的望远镜效果,首先,还是自定义控件,毕竟这一个专栏都是自定义控件,基本每篇都少不了这个步骤,代码如下:

public class BitmapShaderView extends View {private Paint paint;//画笔工具private Bitmap bgBitmap,bitmap;//隐藏图像以及原图像private int mX=-1,mY=-1;//捕获手指的位置坐标public BitmapShaderView(Context context) {super(context);}public BitmapShaderView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);this.paint=new Paint();//初始化画笔工具this.bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.background);//获取原图像}public BitmapShaderView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}
}

详细注解,应该可以理解了,这里就不在做过多的赘述,接下来,我们需要捕获手指下按,移动以及离开屏幕的手指所在位置,也就是重写onTouchEvent()函数:

public boolean onTouchEvent(MotionEvent event) {switch (event.getAction()){case MotionEvent.ACTION_DOWN://手指按下事件this.mX=(int)event.getX();this.mY=(int)event.getY();postInvalidate();//重绘return true;case MotionEvent.ACTION_MOVE://手指移动事件this.mX=(int)event.getX();this.mY=(int)event.getY();break;case MotionEvent.ACTION_UP://手指抬起case MotionEvent.ACTION_CANCEL://手指离开事件this.mX=-1;this.mY=-1;break;}postInvalidate();//重绘return super.onTouchEvent(event);
}

这里捕获了移动以及按下手指的坐标,这样就可以定位望远镜的位置,而当手指抬起的时候,望远镜效果就不见了,所以必须设置他们坐标为-1。最后是绘图代码,onDraw()实现:

protected void onDraw(Canvas canvas) {super.onDraw(canvas);if(this.bgBitmap==null){this.bgBitmap=Bitmap.createBitmap(getWidth(),getHeight(),Bitmap.Config.ARGB_8888);//创建一个新空白位图Canvas canvasBg=new Canvas(this.bgBitmap);//然后对背景图拉升后,画到上面的位图中canvasBg.drawBitmap(this.bitmap,null,new Rect(0,0,getWidth(),getHeight()),this.paint);}if(this.mX!=-1 && this.mY!=-1){//填充模式为上面讲的第二种,就是复制粘贴的填充模式,但这里不会执行//因为我们上面强制设置了图片的大小为整个屏幕,所以屏幕没有空白区域this.paint.setShader(new BitmapShader(this.bgBitmap,     Shader.TileMode.REPEAT,Shader.TileMode.REPEAT));canvas.drawCircle(this.mX,this.mY,200,this.paint);}
}

这里我们首先创建了一个空白位图,然后对原图像进行拉升后画到这张位图中,接着,根据设置画笔的填充模式,这里其实没用,是因为我们拉升了图像,并没有空白区域,最后,我们根据手指坐标,将望远镜效果绘制到手机界面中,这样望远镜效果的自定义控件完美实现了。

GitHub源代码下载地址:点击下载

Android自定义控件(四)——望远镜效果实现相关推荐

  1. android 自定义view之雷达扫描,基于Android自定义控件实现雷达效果

    如何制作出类似雷达扫描的效果,具体方法如下 一.效果图 二.实现思路 1.自定义控件RadarView用来画雷达的效果图,可以自定义属性包括 backgroundColor:背景颜色 circleNu ...

  2. Android自定义控件(四)仿网易客户端上拉加载更多

    上一篇仿得网页客户端的抽屉模式,这一篇继续,来写一写加载更多这个功能,通过自定义实现加载更多,先上图: 今天实现的就是如图中最下面的20条载入中...这个功能啦! 先来说一下思路: 1.在listvi ...

  3. 自定义控件三部曲之绘图篇(十八)——BitmapShader与望远镜效果

    上篇初步给大家展示了封装控件的方法,这篇我们继续Paint来看相关方法的用法,这篇我们将会讲一个很起来没啥用,但效果却很屌的方法setShader,这篇文章最后,我们将实现的效果是望远镜效果:(看起来 ...

  4. 自定义控件android特效,Android自定义控件eBook实现翻书效果实例详解

    本文实例讲述了Android自定义控件eBook实现翻书效果的方法.分享给大家供大家参考,具体如下: 效果图: Book.java文件: package com.book; import androi ...

  5. Android 自定义控件之圆形页面指示器CirclePageIndicator带划动效果

    Android 自定义控件之圆形页面指示器CirclePageIndicator带划动效果 前言 感谢 效果图 目标 流程 自定义属性 自定义默认属性 自定义接口 创建控件类继承View 声明属性变量 ...

  6. Android自定义控件系列

    原文出处:http://blog.csdn.net/harvic880925/article/details/50995268 前言:在我从C++转到Android时,就被Android里炫彩斑斓的自 ...

  7. 原 Android自定义控件三部曲文章索引

    转自 https://blog.csdn.net/harvic880925/article/details/50995268 前言:在我从C++转到Android时,就被Android里炫彩斑斓的自定 ...

  8. Android自定义控件三部曲文章索引

    前言:在我从C++转到Android时,就被Android里炫彩斑斓的自定义控件深深折服,想知道如果想利用C++实现这些功能,那是相当困难的.从那时候起,我就想,等我学会了自定义控件,一定要写一篇系列 ...

  9. Android自定义控件三部曲

    Android自定义控件 一.自定义控件三部曲之动画篇 1.<自定义控件三部曲之动画篇(一)--alpha.scale.translate.rotate.set的xml属性及用法> 2.& ...

最新文章

  1. 为何Java中子类重写方法的访问权限不能低于父类中权限
  2. 模拟退火算法通俗讲解
  3. php fastcgi,配置apache以fastcgi运行php
  4. silverlight中如何方便在多个场景即Xaml文件之间随意切换?
  5. Transformation HDU - 6726(百度之星复赛2019 dfs)
  6. 在批处理文件中启动MediaPlayer播放制定文件
  7. 发展之道:简单与专注
  8. 苹果x来电闪光灯怎么设置_苹果6splus来电没有声音,苹果6sp听筒没有声音怎么回事...
  9. gentoo Portage使用
  10. 网易云数据库容灾策略
  11. [JSOI2008] 最小生成树计数
  12. 【转】Windows下部署Appium教程(Android App自动化测试框架搭建)
  13. 金华市电子计算机学校,金华市第十四届中小学生计算机竞赛结果
  14. Centos 7 部署 OpenStack_Rocky版高可用集群3-1
  15. css制作导航栏的三角形
  16. SMT32F407+FreeRTOS+LWIP+LAN8720使用Cube MX情况下无法实现网线热插拔
  17. Python实现淘宝爬取——奶粉销售信息爬取及其数据可视化
  18. JS文件应该放在什么位置
  19. 12. Vuepress2.x 隐藏指定页的 sidebar
  20. JavaScript基础——JS编译器你都做了啥?

热门文章

  1. 网络结构拓扑图(3层交换机)
  2. 什么是Qt Widget?
  3. Python 关键字global全局变量详解
  4. 小kk计算机,有过停学记录又怎样,仍能与胡歌、小KK做校友!
  5. animators vs animations
  6. 2023年5月计薪天数是多少天,五一加班费怎么算
  7. sd卡的照片误删了怎么办 不小心删了sd卡的照片
  8. 吐血整理|3D视觉系统化学习路线
  9. JavaWeb开发调用支付宝接口实现在线支付(整个支付过程从头到尾)
  10. 微信跨公众号支付(appid 与 openid 不匹配)