Android剪切板(ClipBoardManager)复制的内容,可以粘贴到任何地方,对于一些词典,翻译工具等app具有较高的使用价值。有道词典在3.6版本后就使用到该功能,本文来剖析具体的实现过程。

首先看一下有道词典的效果图:

SDK使用说明,API 11以上请导入包:android.content.ClipboardManager。

具体实现流程如下:

a.开启后台监听服务。

在服务创建的过程中,启动剪切板,设置内容监听器。

[java]  view plain copy
  1. final ClipboardManager cm = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
  2. cm.addPrimaryClipChangedListener(new OnPrimaryClipChangedListener() {
  3. @Override
  4. public void onPrimaryClipChanged() {
  5. ClipData data = cm.getPrimaryClip();
  6. Item item = data.getItemAt(0);
  7. Intent mIntent = new Intent();
  8. mIntent.setAction("com.cybertron.dict.ClipBoardReceiver");
  9. mIntent.putExtra("clipboardvalue", item.getText().toString());
  10. sendBroadcast(mIntent);
  11. }
  12. });

这里要注意的是API11后,1.获取剪切板内容的操作均在ClipData中;2.这里的监听接口OnPrimaryClipChangedListener,是添加而不是设置。当剪切板内容发生改变时,回调执行onPrimaryClipChanged方法,如果设备有多个这样的监听的话,该方法会执行多次,但影响不大。

b.获取剪切板内容,启动浮动窗口。

剪切板内容发生改变后,可以通过发送广播或服务的方式进行数据传输。本文通过的是前者的方式,广播接收器接收到传值后再启动浮动窗口的服务。

浮动窗口接收传值并显示,并可以拖动。具体实现参考:

[java]  view plain copy
  1. public class FloatingWindowService extends Service{
  2. public static final String OPERATION = "operation";
  3. public static final int OPERATION_SHOW = 100;
  4. public static final int OPERATION_HIDE = 101;
  5. private boolean isAdded = false; // 是否已增加悬浮窗
  6. private static WindowManager wm;
  7. private static WindowManager.LayoutParams params;
  8. private View floatView;
  9. private float startX = 0;
  10. private float startY = 0;
  11. private float x;
  12. private float y;
  13. private String copyValue;
  14. @Override
  15. public IBinder onBind(Intent intent) {
  16. return null;
  17. }
  18. @Override
  19. public void onCreate() {
  20. super.onCreate();
  21. createFloatView();
  22. }
  23. @Override
  24. public void onDestroy() {
  25. super.onDestroy();
  26. }
  27. @Override
  28. public void onStart(Intent intent, int startId) {
  29. super.onStart(intent, startId);
  30. if (intent != null) {
  31. int operation = intent.getIntExtra(OPERATION, OPERATION_SHOW);
  32. switch (operation) {
  33. case OPERATION_SHOW:
  34. if (!isAdded) {
  35. wm.addView(floatView, params);
  36. isAdded = true;
  37. }
  38. break;
  39. case OPERATION_HIDE:
  40. if (isAdded) {
  41. wm.removeView(floatView);
  42. isAdded = false;
  43. }
  44. break;
  45. }
  46. copyValue = intent.getStringExtra("copyValue");
  47. setupCellView(floatView);
  48. Log.e(this.getClass().getSimpleName(), "=====copyValue :"+copyValue);
  49. }
  50. }
  51. /**
  52. * 创建悬浮窗
  53. */
  54. private void createFloatView() {
  55. LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  56. floatView = layoutInflater.inflate(R.layout.dict_popup_window, null);
  57. wm = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
  58. params = new WindowManager.LayoutParams();
  59. // 设置window type
  60. params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
  61. /*
  62. * 如果设置为params.type = WindowManager.LayoutParams.TYPE_PHONE; 那么优先级会降低一些,
  63. * 即拉下通知栏不可见
  64. */
  65. params.format = PixelFormat.RGBA_8888; // 设置图片格式,效果为背景透明
  66. // 设置Window flag
  67. params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
  68. | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
  69. /*
  70. * 下面的flags属性的效果形同“锁定”。 悬浮窗不可触摸,不接受任何事件,同时不影响后面的事件响应。
  71. * wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL |
  72. * LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_NOT_TOUCHABLE;
  73. */
  74. // 设置悬浮窗的长得宽
  75. params.width = getResources().getDimensionPixelSize(R.dimen.float_width);
  76. params.height = WindowManager.LayoutParams.WRAP_CONTENT;
  77. params.gravity = Gravity.LEFT | Gravity.TOP;
  78. params.x = 0;
  79. params.y = 0;
  80. // 设置悬浮窗的Touch监听
  81. floatView.setOnTouchListener(new OnTouchListener() {
  82. @Override
  83. public boolean onTouch(View v, MotionEvent event) {
  84. x = event.getRawX();
  85. y = event.getRawY();
  86. switch(event.getAction()){
  87. case MotionEvent.ACTION_DOWN:
  88. startX = event.getX();
  89. startY = event.getY();
  90. break;
  91. case MotionEvent.ACTION_MOVE:
  92. params.x = (int)( x - startX);
  93. params.y = (int) (y - startY);
  94. wm.updateViewLayout(floatView, params);
  95. break;
  96. case MotionEvent.ACTION_UP:
  97. startX = startY = 0;
  98. break;
  99. }
  100. return true;
  101. }
  102. });
  103. wm.addView(floatView, params);
  104. isAdded = true;
  105. }
  106. /**
  107. * 设置浮窗view内部子控件
  108. * @param rootview
  109. */
  110. private void setupCellView(View rootview) {
  111. ImageView closedImg = (ImageView) rootview.findViewById(R.id.float_window_closed);
  112. TextView titleText = (TextView) rootview.findViewById(R.id.float_window_title);
  113. titleText.setText(copyValue);
  114. closedImg.setOnClickListener(new OnClickListener() {
  115. @Override
  116. public void onClick(View v) {
  117. if (isAdded) {
  118. wm.removeView(floatView);
  119. isAdded = false;
  120. }
  121. }
  122. });
  123. floatView.setOnClickListener(new OnClickListener() {
  124. @Override
  125. public void onClick(View v) {
  126. }
  127. });
  128. }
  129. }

android有道词典简单开发相关推荐

  1. Android有道词典开发

    第一步,申请API key,申请地址:http://fanyi.youdao.com/openapi?path=data-mode 数据接口: http://fanyi.youdao.com/open ...

  2. Android有道词典查询功能

    有道词典 任务要求:完成查词等功能 因为需要申请API key,这里直接给出地址供使用:http://fanyi.youdao.com/openapi?path=data-mode 1.activit ...

  3. 仿有道词典App开发

    最近在学习HCoder提供的仿有道词典App项目,该项目采用MUI为前端框架,服务端采用PHP,底层采用了H5+. 转载于:https://www.cnblogs.com/helloup/p/7997 ...

  4. 简易词典Android界面代码,Android 有道词典的简单实现方法介绍

    第一步:思路解析 从界面看一共用了三个控件EditText,Button,WebView.其实是四个,是当我们查询内容为空的时候用来提示的Toast控件.我们在EditText输入查询内容,这里包括中 ...

  5. 关于android有道词典的修改

    本文是关于第一篇博文里的项目布局的修改 将main.xml里面的绝对布局改为线性布局即可,感觉这样看起来舒服些! <?xml version="1.0" encoding=& ...

  6. android 网页词典,android 有道词典查询单词(webview版)

    [实例简介] [实例截图] [核心代码] package com.example.youdaodictionary; import android.app.Activity; import andro ...

  7. android简单的有道词典开发

    简单的android有道词典开发 第一次写教程,不好勿怪哈!其实想写这篇教程已经很久了,但却一直没有付诸行动,这个项目是偶然间在论坛里发现的,我算是弄出来整理了一下吧!所以在此要感谢那些前辈们,没有他 ...

  8. android蓝牙简单开发

    概述 前段时间学习了一些蓝牙开发的知识,记录一下Android中蓝牙的简单开发.下面是最重要的两个类. BluetoothAdapter : 蓝牙适配器,通过getDefaultAdapter ()去 ...

  9. Android进阶2之有道词典开发

    本博文只是实现有道词典的功能,并着重界面. 首先,你需要获取有道开发平台的API key.点击打开链接 申请一个吧. 利用数据接口获取数据: http://fanyi.youdao.com/opena ...

最新文章

  1. 光流 | 基于Matlab实现Lucas-Kanade方法:方法2(附源代码)
  2. 揭秘:高盛交易员赚取10亿美元利润的神秘“利器”终于公开了
  3. Redis Hash 类型操作及常用命令
  4. AndroidStudio中添加第三库文件的方法
  5. 处理下载文件时中文乱码
  6. 录音机 在launcher中显示_「 腾讯 微信事业部 社招二面」——一个APP从启动到主页面显示经历了哪些过程?...
  7. 力扣868. 二进制间距
  8. Android C++ OpenGL教程课程总结
  9. 文学家是什么时候出现的
  10. 【算法】02 SCE-UA简介及源代码
  11. Jframe任务栏图标隐藏
  12. 迅雷 linux 命令行 版本号,在Linux系统下使用wine运行迅雷5的方法
  13. 简易的微信公众号管理平台使用指南
  14. java informix_Informix 数据库的数据类型
  15. Postman教程——发送第一个请求
  16. 从零构建通讯器--7.1过往总结和心跳包代码实战
  17. MySQL自带的性能压力测试工具mysqlslap详解
  18. 如何优雅的使用DbContext
  19. 何以雾霾多妩媚,只在此间总朦胧
  20. 错误 3002: 映射从第 10323 行开始的片段时有问题:表 T_BillTripDetail 的键(T_BillTripDetail.DetailGUID)具有潜在运行时冲突: 列(T_Bill

热门文章

  1. 【回眸】软件测试中NA/OK/POK?NG/NT是什么意思?一些公司职位的缩写眼花缭乱,它们到底是什么的缩写?
  2. Java实现PDF导出功能
  3. 高精度电流源如何设计出来?
  4. 极客返利上线啦|网课返现、返利平台
  5. 计算机指令系统代码设计,指令系统
  6. HBase数据库的基本操作增删改查
  7. java 缓冲区溢出_缓冲区溢出详解
  8. 快速掌握差分进化算法
  9. 上海宝付金融网络安全意识普及
  10. Centos qW3xT.2 挖矿病毒