开源地址:https://github.com/jcodeing/ExtractWordView
效果图:

怎么实现的?
通过事件分发机制判断手指的落点处,剪取手指落点处的矩形区域,然后显示在PopupWindow里面.
第一步:自定义ListView

public class EWListView extends ListView

第二步:自定义一个Magnifier继承自view存放截图的屏幕图像(截取屏幕图像的时候应该做好边界判断控制),然后将这个view放入PopupWindow中悬浮展示。也就是那个放大镜。

    private void initMagnifier() {BitmapDrawable resDrawable = (BitmapDrawable) context.getResources().getDrawable(R.drawable.ic_launcher1);resBitmap = resDrawable.getBitmap();magnifier = new Magnifier(context);//pop在宽高的基础上多加出边框的宽高popup = new PopupWindow(magnifier, WIDTH + 2, HEIGHT + 10);popup.setAnimationStyle(android.R.style.Animation_Toast);dstPoint = new Point(0, 0);}
    class Magnifier extends View {private Paint mPaint;public Magnifier(Context context) {super(context);mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setColor(0xffff0000);mPaint.setStyle(Paint.Style.STROKE);}@Overrideprotected void onDraw(Canvas canvas) {canvas.save();// draw popupmPaint.setAlpha(255);canvas.drawBitmap(resBitmap, 0, 0, mPaint);canvas.restore();//draw popup framemPaint.reset();//重置mPaint.setColor(Color.LTGRAY);mPaint.setStyle(Paint.Style.STROKE);//设置空心mPaint.setStrokeWidth(2);Path path1 = new Path();path1.moveTo(0, 0);path1.lineTo(WIDTH, 0);path1.lineTo(WIDTH, HEIGHT);path1.lineTo(WIDTH / 2 + 15, HEIGHT);path1.lineTo(WIDTH / 2, HEIGHT + 10);path1.lineTo(WIDTH / 2 - 15, HEIGHT);path1.lineTo(0, HEIGHT);path1.close();//封闭canvas.drawPath(path1, mPaint);}}

其中resBitmap就是截取的屏幕图像,通过划线的方式画出了一个倒三角的效果。
第三步:onTouchEvent(MotionEvent event) 在MotionEvent.ACTION_MOVE,通过手指点x,y坐标计算出popup显示的坐标,在手指点的正上方,每一次MotionEvent.ACTION_MOVE事件的到来都更新一次popup的位置。

popup.update(getLeft() + dstPoint.x, getTop() + dstPoint.y, -1, -1);

基本上按照上述步骤已经完成了,只需了解原理,死磕代码会浪费比较多的事件。
接下来看一下辅助功能,截取屏幕:

    /*** @param activity* @param x        截图起始的横坐标* @param y        截图起始的纵坐标* @param width* @param height* @return*/private Bitmap getBitmap(Activity activity, int x, int y, int width, int height) {View view = activity.getWindow().getDecorView();view.setDrawingCacheEnabled(true);view.buildDrawingCache();Bitmap bitmap;//生成的位图bitmap = view.getDrawingCache();//边界处理,否则会崩滴if (x < 0)x = 0;if (y < 0)y = 0;if (x + width > bitmap.getWidth()) {//保持不改变,截取图片宽高的原则x = bitmap.getWidth() - width;}if (y + height > bitmap.getHeight()) {y = bitmap.getHeight() - height;}Rect frame = new Rect();activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);bitmap = Bitmap.createBitmap(bitmap, x, y, width, height);view.setDrawingCacheEnabled(false);return bitmap;}

大致意思是获取Activity的顶级View也就是DecorView,是一个FrameLayout。拿到这个activity的Bitmap视图,bitmap = view.getDrawingCache();基于这个activity视图,截取以x,y为左上角顶点,宽度和高度分别为with,height的矩形,bitmap =Bitmap.createBitmap(bitmap, x, y, width, height);然后将得到的bitmap赋值给srcBitmap在Magnifier的onDraw里面重绘就行OK了。

获取文字:
1.先找到自定义的EditText

  EWListViewChildET findMotionView(int x, int y) {//是否从顶部开始find提高效率boolean isTopStart = y < getHeight() / 2;int childCount = getChildCount();if (childCount > 0) {if (isTopStart) {for (int i = 0; i < childCount; i++) {if (!(getChildAt(i) instanceof EWListViewChildET))return null;EWListViewChildET v = (EWListViewChildET) getChildAt(i);if (y <= v.getBottom()) {//特殊处理--更新EditText--相对自己的x,yv.y = y - v.getTop();v.x = x;Log.e("J", "ET-->y::" + y + "--updata->" + v.y);return v;}}} else {for (int i = childCount - 1; i >= 0; i--) {if (!(getChildAt(i) instanceof EWListViewChildET))return null;EWListViewChildET v = (EWListViewChildET) getChildAt(i);if (y >= v.getTop()) {v.y = y - v.getTop();v.x = x;Log.e("J", "ET-->y::" + y + "--updata->" + v.y);return v;}}}}return null;}

类似于二分查找的方式,先通过isTopStart来判断是从上往下查找还是从下往上查找(提高查找效率),然后就是遍历每个item,看x,y有没有落到他的区域内,如果是就返回该自定义EditText.

2.得到按压的文字
1)首先得到按压位置的偏移,相对于本item本身,这个x,y是在findMotionView里面赋值的。

    public int extractWordCurOff(Layout layout, int x, int y) {int line;line = layout.getLineForVertical(getScrollY() + y - 10);int curOff = layout.getOffsetForHorizontal(line, x);return curOff;}

2)通过手指位置相对于item的偏移计算出当前按压的文字:

    public String getSelectWord(Editable content, int curOff) {String word = "";int start = getWordLeftIndex(content, curOff);int end = getWordRightIndex(content, curOff);if (start >= 0 && end >= 0) {word = content.subSequence(start, end).toString();if (!"".equals(word)) {// setFocusable(false);et.setFocusableInTouchMode(true);et.requestFocus();Selection.setSelection(content, start, end);// 设置当前具有焦点的文本字段的选择范围,当前文本必须具有焦点,否则此方法无效}}return word;}

3)计算出截取问题的其实位置
截取的开始位置索引:

 public int getWordLeftIndex(Editable content, int cur) {// --leftString editableText = content.toString();// getText().toString();if (cur >= editableText.length())return cur;int temp = 0;//单词的长度一般不会超过20位,将temp索引往前推移20位if (cur >= 20)temp = cur - 20;//正则表达式匹配单词开头Pattern pattern = Pattern.compile("[^'A-Za-z]");Matcher m = pattern.matcher(editableText.charAt(cur) + "");//找到就返回索引if (m.find())return cur;String text = editableText.subSequence(temp, cur).toString();//没有找到就,从索引处往前面扫描,知道找到匹配的为止返回该处的索引int i = text.length() - 1;for (; i >= 0; i--) {Matcher mm = pattern.matcher(text.charAt(i) + "");if (mm.find())break;}int start = i + 1;start = cur - (text.length() - start);return start;}

不清楚的地方可以看注释
截取结束位置索引:

    public int getWordRightIndex(Editable content, int cur) {// --rightString editableText = content.toString();if (cur >= editableText.length())return cur;int templ = editableText.length();if (cur <= templ - 20)templ = cur + 20;Pattern pattern = Pattern.compile("[^'A-Za-z]");Matcher m = pattern.matcher(editableText.charAt(cur) + "");if (m.find())return cur;String text1 = editableText.subSequence(cur, templ).toString();int i = 0;for (; i < text1.length(); i++) {Matcher mm = pattern.matcher(text1.charAt(i) + "");if (mm.find())break;}int end = i;end = cur + end;return end;}

原理跟寻找开始位置一样。

然后就可以根据开始位置和结束位置截取字符串了:

word = content.subSequence(start, end).toString()

OK,结束。

Android 放大镜效果实现原理相关推荐

  1. 仿京东PC网页商品详情的放大镜效果(原理+代码)

    实现效果 黑色只不过是转gif出问题而已 准备工作 1. 访问该网址,理解我们要弄的放大镜效果,鼠标经过商品图片,显示一个黄色的放大选区,右边显示该选区的大图. 2. 获取商品图片和商品大图 [摩托罗 ...

  2. 【jQuery】前端项目实践案例6——制作产品放大镜效果(仿京东淘宝图片效果)

    使用jQuery制作产品放大镜效果实现效果: 使用jQuery制作产品放大镜效果实现原理: 通过设置图像的 CSS 属性( left 和 top ),来实现图像的移动. 使用jQuery制作产品放大镜 ...

  3. android 放大镜动画,Android在图片上进行放大镜效果(放大镜形状)

    Android 图片上放大镜效果实现 1.[文件] ZoomView.java ~ 5KB     下载(55) package com.study.hello; import android.con ...

  4. android 使用BitmapShader实现圆形以及放大镜效果

    在一些显示用户头像的时候,大多数都是显示圆形的,而不是显示一个正方形或者长方形,这样显得很呆板,视觉效果也不好看,今天就用二种方式实现图片圆形显示的效果,在先讲这个效果实现之前,讲下BitmapSha ...

  5. html放大镜原理,Canvas实现放大镜效果完整案例分析(附代码)

    本文主要记录 canvas 在图像.文字处理.离屏技术和放大镜特效的实现过程中使用到的API.先看下效果吧: 一张模糊的图片: 鼠标点击任意位置,产生放大效果: 哇塞~ 一个帅哥,哈哈哈哈~ 1.放大 ...

  6. Android手机与vr交互暴风魔镜3D效果显示原理

    首先讲到VR,谈谈个人体会,半年前看到淘宝上的vr眼镜盒为了促销标题图片都是非常性感的,还有海量你懂得资源.到最近在淘宝搜索vr暴风魔镜都正规了,而且销售量庞大 还有新闻上很多vr的科技前沿资讯可以看 ...

  7. 高级UI - Paint基本使用.高级渲染使用(最后实现放大镜效果)

    Paint 基本使用 <Paint的方法主要可以抽象成两大类>: 1.1 负责设置获取图形绘制.路径相关的1.setStyle(Paint.Style style) 设置画笔样式,取值有P ...

  8. html中放大镜案列,Canvas实现放大镜效果完整案例分析(附代码)

    本文主要记录 canvas 在图像.文字处理.离屏技术和放大镜特效的实现过程中使用到的api.先看下效果吧: 一张模糊的图片: 鼠标点击任意位置,产生放大效果: 哇塞~ 一个帅哥,哈哈哈哈~ 1.放大 ...

  9. android翻页实现原理

    Android平台中的二种翻页效果实现. 第一种翻页效果如下: 实现原理: 当前手指触摸点为a,则 a点坐标为(ax,ay), 由三角形acb与三角形cmb为对称三角形并且直线cp为am垂直平分线,则 ...

  10. Qt 实现钢笔画线效果详细原理

    前言 上一篇文章:Qt 实现画线笔锋效果详细原理,根据这篇介绍的实现笔锋效果的原理,我们很容易实现另外一种笔效:钢笔. 所谓的钢笔笔效,就是真实还原钢笔书写出来的线条效果,其特征就是:根据笔的绘制速度 ...

最新文章

  1. Django ModelForm操作及验证
  2. sersync2 完全安装配置说明(三) ----插件基本配置和使用
  3. 【Groovy】集合遍历 ( 使用集合的 reverseEach 方法进行遍历 | 倒序集合迭代器 ReverseListIterator 类简介 | 代码示例 )
  4. range在c语言中的意思,“range”的含义,你get到了吗?
  5. [HEOI2016/TJOI2016]求和
  6. 招聘职位:ERP咨询顾问(广州、厦门)
  7. jquery ajax json转换出错Invalid JSON
  8. linux 脚本 发送邮件,shell 脚本发送邮件
  9. MySQL 基础模块的面试题总结
  10. 【Java】application run failed Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and
  11. 使用方法_山西硅肥使用方法
  12. RaspberryPi(一)
  13. 关于 rm -rf * 你需要知道的
  14. C 语言调用python 脚本函数
  15. 百度音乐 android,百度音乐旧版本
  16. 查看本地计算机ip命令,查看你本机的IP信息的命令ipconfig详解【图】
  17. 小米怎么快速回到顶部_实在没想到,小米有6种截屏方法!以前只知道3种,实在太吃亏了...
  18. c++游戏编程初步(超简单)教学
  19. 什么是一体化管理体系
  20. Codeforces 854 B Maxim Buys an Apartment

热门文章

  1. 计算机组成原理:原,反,补码,加减运算,溢出判断,符号扩展
  2. English--动名词
  3. 职场必备:十句外企 office 常用英语
  4. html alt 作用,什么是alt标签的作用,alt标签对SEO有哪些影响呢?
  5. catboost介绍
  6. 无为而无不为——论老子哲学的深度悖论(转载)
  7. 团队管理19--团队分工
  8. 织梦cms仿站_文章发布出现WTS-WAF页面
  9. html 强制用ie浏览,强制指定IE浏览器版本
  10. CNC加工中心的刀具补偿详解