android自定义view实现"偷窥"图片
2015-10-29 22:12
162 查看
今天实现了利用自定义view实现了一个查看被遮盖的图片功能,不过是通过”偷窥”这种行为实现的,其实这种功能我也不知道怎么命名,就暂且叫他”偷窥”图片,先看下效果吧:
ok,其实该功能和刮刮卡的原理是一样的,只不过刮刮卡对于上层的覆盖层只绘制了一次,所以每次擦除部分是不会恢复的,而对于该实例,上面的图层是每次重绘的时候都会重新绘制的,下实现该功能的原理:
在onDraw方法提供的canvas中绘制该图片
在onDraw方法提供的canvas中绘制一个和该图片相同大小的bitmap
设置当前画笔的xformode=DST_IN,以及颜色透明,这样才可以看到下面这张图片
绘制当前的圆形,注意需要设置该圆半径的初始值=0,这样不至于一开始就可以看到底层图片
重写onTouchEvent,在用户触摸该view时候,将半径更改到一定的值,并且在手指移动的时候,重新设置当前圆的圆心坐标,在手指抬起的时候,将半径重置为0,重绘,这样就实现了上面的功能。
这里和我上面描述的原理是一样的,先绘制一个图片,然后绘制一个相同大小的bitmap,遮挡住该图片,设置Paint的模式和透明色,绘制圆。
代码注释的比较详细,就不做过多解释了,注意一点,在做边界条件判断的时候,由于最下面的地方需要将手机状态栏的高度考虑进去,因为我们是和整个屏幕的高度来做比较的。
可以看到这里我使用资源id首先查找到资源id,然后通过getResources来查看具体的值。
ok,今天的博客就到这里了,希望大家能够喜欢。
源码下载
ok,其实该功能和刮刮卡的原理是一样的,只不过刮刮卡对于上层的覆盖层只绘制了一次,所以每次擦除部分是不会恢复的,而对于该实例,上面的图层是每次重绘的时候都会重新绘制的,下实现该功能的原理:
实现思路
首先将准备好的图片缩放至和屏幕大小相同在onDraw方法提供的canvas中绘制该图片
在onDraw方法提供的canvas中绘制一个和该图片相同大小的bitmap
设置当前画笔的xformode=DST_IN,以及颜色透明,这样才可以看到下面这张图片
绘制当前的圆形,注意需要设置该圆半径的初始值=0,这样不至于一开始就可以看到底层图片
重写onTouchEvent,在用户触摸该view时候,将半径更改到一定的值,并且在手指移动的时候,重新设置当前圆的圆心坐标,在手指抬起的时候,将半径重置为0,重绘,这样就实现了上面的功能。
重写onDraw方法
[code]@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //创建一个当前屏幕大小的dstBitmap并根据该dstBitmap创建相同大小的mDstCanvas mDstBtimap = Bitmap.createBitmap(screenWidth, screenHeight, Config.ARGB_8888); mDstCanvas = new Canvas(mDstBtimap); mDstCanvas.drawColor(Color.parseColor("#ccc568")); //获得mSrcBitmap,并将其缩放至和屏幕大小相同 mSrcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.system); mSrcBitmap = Bitmap.createScaledBitmap(mSrcBitmap, screenWidth, screenHeight, false); //先绘制底层的图片,然后绘制相同大小的mDstBtimap使其覆盖底层的图皮 canvas.drawBitmap(mSrcBitmap, 0, 0, null); canvas.drawBitmap(mDstBtimap, 0, 0,null); mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); mPaint.setColor(Color.argb(20,255,0,0));//设置此时的画笔为透明,所以可以看到底层的图片 mDstCanvas.drawCircle(mCurrentX, mCurrentY, mShowCircleRadius, mPaint); }
这里和我上面描述的原理是一样的,先绘制一个图片,然后绘制一个相同大小的bitmap,遮挡住该图片,设置Paint的模式和透明色,绘制圆。
重写onTouchEvent
[code]@Override public boolean onTouchEvent(MotionEvent event) { //每次onTouchEvent方法调用的时候需要重新将手指按下的坐标赋值给圆心坐标,否做会出现当手指抬起后再次按下时候,会在上一个手指抬起时候的坐标显示 //因为mCurrentX 和mCurrentY最后的值就是手指抬起时候的按下的值 mCurrentX = event.getX(); mCurrentY = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //当手指按下的时候,将当前圆的半径变为一定的值 mShowCircleRadius += mRadius; break; case MotionEvent.ACTION_MOVE: //获取当前手指按下的坐标,将将其标注为圆心 mCurrentX = event.getX(); mCurrentY = event.getY(); //边界条件判断 mCurrentX = mCurrentX < mRadius ? mRadius : mCurrentX; mCurrentY = mCurrentY < mRadius ? mRadius : mCurrentY; mCurrentX = (mCurrentX + mRadius) > screenWidth ? (screenWidth - mRadius) : mCurrentX; mCurrentY = (mCurrentY + mRadius + getStatusBarHeight()) > screenHeight ? (screenHeight - mRadius - getStatusBarHeight()) : mCurrentY; Log.d(TAG, "the mCurrentY is :"+mCurrentY+"====the screenHeight is :"+screenHeight+":status bar:"+getStatusBarHeight()); break; case MotionEvent.ACTION_UP: mShowCircleRadius = 0; break; default: break; } invalidate(); return true; }
代码注释的比较详细,就不做过多解释了,注意一点,在做边界条件判断的时候,由于最下面的地方需要将手机状态栏的高度考虑进去,因为我们是和整个屏幕的高度来做比较的。
获取状态栏的高度
[code]private int getStatusBarHeight(){ int height=0; int resouceId=getResources().getIdentifier("status_bar_height", "dimen", "android"); if(resouceId>0){ height=getResources().getDimensionPixelSize(resouceId); } return height; }
可以看到这里我使用资源id首先查找到资源id,然后通过getResources来查看具体的值。
ok,今天的博客就到这里了,希望大家能够喜欢。
源码下载
相关文章推荐
- Android开发中Handler的经典总结
- Android中显示意图和隐式意图
- AndroidTest
- Android Touch事件的分发响应机制
- Android Studio中Button ,Textview中字体自动变成大写的问题
- AndroidStudio实用插件收集
- 解决Android抽屉被击穿问题
- 日报2015/10/29(极客学院安卓视频学习)
- Android 配置文件 manifest 子节点属性说明
- Android中的“再按一次返回键退出程序”实现
- Android实现推送方式解决方案
- 【Android】实现打开关闭效果
- Android抽屉(SlidingDrawer --类似android通知栏下拉效果)
- 用户注册--Android
- 【Android成长之路】全局大喇叭——广播机制的浅谈(发送自定义广播)
- Android开发手记(18) 数据存储三 SQLite存储数据
- Android JS相互调用详解
- Android基础入门教程——10.6 PowerManager(电源服务)
- 使用Android Studio进行NDK开发
- android studio使用jcenter上的开源库