android有道词典简单开发
Android剪切板(ClipBoardManager)复制的内容,可以粘贴到任何地方,对于一些词典,翻译工具等app具有较高的使用价值。有道词典在3.6版本后就使用到该功能,本文来剖析具体的实现过程。
首先看一下有道词典的效果图:
SDK使用说明,API 11以上请导入包:android.content.ClipboardManager。
具体实现流程如下:
a.开启后台监听服务。
在服务创建的过程中,启动剪切板,设置内容监听器。
- final ClipboardManager cm = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
- cm.addPrimaryClipChangedListener(new OnPrimaryClipChangedListener() {
- @Override
- public void onPrimaryClipChanged() {
- ClipData data = cm.getPrimaryClip();
- Item item = data.getItemAt(0);
- Intent mIntent = new Intent();
- mIntent.setAction("com.cybertron.dict.ClipBoardReceiver");
- mIntent.putExtra("clipboardvalue", item.getText().toString());
- sendBroadcast(mIntent);
- }
- });
这里要注意的是API11后,1.获取剪切板内容的操作均在ClipData中;2.这里的监听接口OnPrimaryClipChangedListener,是添加而不是设置。当剪切板内容发生改变时,回调执行onPrimaryClipChanged方法,如果设备有多个这样的监听的话,该方法会执行多次,但影响不大。
b.获取剪切板内容,启动浮动窗口。
剪切板内容发生改变后,可以通过发送广播或服务的方式进行数据传输。本文通过的是前者的方式,广播接收器接收到传值后再启动浮动窗口的服务。
浮动窗口接收传值并显示,并可以拖动。具体实现参考:
- public class FloatingWindowService extends Service{
- public static final String OPERATION = "operation";
- public static final int OPERATION_SHOW = 100;
- public static final int OPERATION_HIDE = 101;
- private boolean isAdded = false; // 是否已增加悬浮窗
- private static WindowManager wm;
- private static WindowManager.LayoutParams params;
- private View floatView;
- private float startX = 0;
- private float startY = 0;
- private float x;
- private float y;
- private String copyValue;
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
- @Override
- public void onCreate() {
- super.onCreate();
- createFloatView();
- }
- @Override
- public void onDestroy() {
- super.onDestroy();
- }
- @Override
- public void onStart(Intent intent, int startId) {
- super.onStart(intent, startId);
- if (intent != null) {
- int operation = intent.getIntExtra(OPERATION, OPERATION_SHOW);
- switch (operation) {
- case OPERATION_SHOW:
- if (!isAdded) {
- wm.addView(floatView, params);
- isAdded = true;
- }
- break;
- case OPERATION_HIDE:
- if (isAdded) {
- wm.removeView(floatView);
- isAdded = false;
- }
- break;
- }
- copyValue = intent.getStringExtra("copyValue");
- setupCellView(floatView);
- Log.e(this.getClass().getSimpleName(), "=====copyValue :"+copyValue);
- }
- }
- /**
- * 创建悬浮窗
- */
- private void createFloatView() {
- LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- floatView = layoutInflater.inflate(R.layout.dict_popup_window, null);
- wm = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
- params = new WindowManager.LayoutParams();
- // 设置window type
- params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
- /*
- * 如果设置为params.type = WindowManager.LayoutParams.TYPE_PHONE; 那么优先级会降低一些,
- * 即拉下通知栏不可见
- */
- params.format = PixelFormat.RGBA_8888; // 设置图片格式,效果为背景透明
- // 设置Window flag
- params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
- /*
- * 下面的flags属性的效果形同“锁定”。 悬浮窗不可触摸,不接受任何事件,同时不影响后面的事件响应。
- * wmParams.flags=LayoutParams.FLAG_NOT_TOUCH_MODAL |
- * LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_NOT_TOUCHABLE;
- */
- // 设置悬浮窗的长得宽
- params.width = getResources().getDimensionPixelSize(R.dimen.float_width);
- params.height = WindowManager.LayoutParams.WRAP_CONTENT;
- params.gravity = Gravity.LEFT | Gravity.TOP;
- params.x = 0;
- params.y = 0;
- // 设置悬浮窗的Touch监听
- floatView.setOnTouchListener(new OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- x = event.getRawX();
- y = event.getRawY();
- switch(event.getAction()){
- case MotionEvent.ACTION_DOWN:
- startX = event.getX();
- startY = event.getY();
- break;
- case MotionEvent.ACTION_MOVE:
- params.x = (int)( x - startX);
- params.y = (int) (y - startY);
- wm.updateViewLayout(floatView, params);
- break;
- case MotionEvent.ACTION_UP:
- startX = startY = 0;
- break;
- }
- return true;
- }
- });
- wm.addView(floatView, params);
- isAdded = true;
- }
- /**
- * 设置浮窗view内部子控件
- * @param rootview
- */
- private void setupCellView(View rootview) {
- ImageView closedImg = (ImageView) rootview.findViewById(R.id.float_window_closed);
- TextView titleText = (TextView) rootview.findViewById(R.id.float_window_title);
- titleText.setText(copyValue);
- closedImg.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (isAdded) {
- wm.removeView(floatView);
- isAdded = false;
- }
- }
- });
- floatView.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- }
- });
- }
- }
android有道词典简单开发相关推荐
- Android有道词典开发
第一步,申请API key,申请地址:http://fanyi.youdao.com/openapi?path=data-mode 数据接口: http://fanyi.youdao.com/open ...
- Android有道词典查询功能
有道词典 任务要求:完成查词等功能 因为需要申请API key,这里直接给出地址供使用:http://fanyi.youdao.com/openapi?path=data-mode 1.activit ...
- 仿有道词典App开发
最近在学习HCoder提供的仿有道词典App项目,该项目采用MUI为前端框架,服务端采用PHP,底层采用了H5+. 转载于:https://www.cnblogs.com/helloup/p/7997 ...
- 简易词典Android界面代码,Android 有道词典的简单实现方法介绍
第一步:思路解析 从界面看一共用了三个控件EditText,Button,WebView.其实是四个,是当我们查询内容为空的时候用来提示的Toast控件.我们在EditText输入查询内容,这里包括中 ...
- 关于android有道词典的修改
本文是关于第一篇博文里的项目布局的修改 将main.xml里面的绝对布局改为线性布局即可,感觉这样看起来舒服些! <?xml version="1.0" encoding=& ...
- android 网页词典,android 有道词典查询单词(webview版)
[实例简介] [实例截图] [核心代码] package com.example.youdaodictionary; import android.app.Activity; import andro ...
- android简单的有道词典开发
简单的android有道词典开发 第一次写教程,不好勿怪哈!其实想写这篇教程已经很久了,但却一直没有付诸行动,这个项目是偶然间在论坛里发现的,我算是弄出来整理了一下吧!所以在此要感谢那些前辈们,没有他 ...
- android蓝牙简单开发
概述 前段时间学习了一些蓝牙开发的知识,记录一下Android中蓝牙的简单开发.下面是最重要的两个类. BluetoothAdapter : 蓝牙适配器,通过getDefaultAdapter ()去 ...
- Android进阶2之有道词典开发
本博文只是实现有道词典的功能,并着重界面. 首先,你需要获取有道开发平台的API key.点击打开链接 申请一个吧. 利用数据接口获取数据: http://fanyi.youdao.com/opena ...
最新文章
- 光流 | 基于Matlab实现Lucas-Kanade方法:方法2(附源代码)
- 揭秘:高盛交易员赚取10亿美元利润的神秘“利器”终于公开了
- Redis Hash 类型操作及常用命令
- AndroidStudio中添加第三库文件的方法
- 处理下载文件时中文乱码
- 录音机 在launcher中显示_「 腾讯 微信事业部 社招二面」——一个APP从启动到主页面显示经历了哪些过程?...
- 力扣868. 二进制间距
- Android C++ OpenGL教程课程总结
- 文学家是什么时候出现的
- 【算法】02 SCE-UA简介及源代码
- Jframe任务栏图标隐藏
- 迅雷 linux 命令行 版本号,在Linux系统下使用wine运行迅雷5的方法
- 简易的微信公众号管理平台使用指南
- java informix_Informix 数据库的数据类型
- Postman教程——发送第一个请求
- 从零构建通讯器--7.1过往总结和心跳包代码实战
- MySQL自带的性能压力测试工具mysqlslap详解
- 如何优雅的使用DbContext
- 何以雾霾多妩媚,只在此间总朦胧
- 错误 3002: 映射从第 10323 行开始的片段时有问题:表 T_BillTripDetail 的键(T_BillTripDetail.DetailGUID)具有潜在运行时冲突: 列(T_Bill