怎么在Android中实现一个自由拖动并显示文字的悬浮框

发布时间:2021-01-27 15:34:05

来源:亿速云

阅读:107

作者:Leah

今天就跟大家聊聊有关怎么在Android中实现一个自由拖动并显示文字的悬浮框,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

实现步骤:

1.首先要设置该悬浮框的基本属性:/**

* 显示弹出框

*

* @param context

*/

@SuppressWarnings("WrongConstant")

public static void showPopupWindow(final Context context, String showtxt) {

if (isShown) {

return;

}

isShown = true;

// 获取WindowManager

mWindowManager = (WindowManager) context

.getSystemService(Context.WINDOW_SERVICE);

mView = setUpView(context, showtxt);

params = new WindowManager.LayoutParams();

// 类型,系统提示以及它总是出现在应用程序窗口之上。

params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT |

WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;

// 设置flag

int flags = canTouchFlags;

// | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

// 如果设置了WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,弹出的View收不到Back键的事件

params.flags = flags;

// 不设置这个弹出框的透明遮罩显示为黑色

params.format = PixelFormat.TRANSLUCENT;

// FLAG_NOT_TOUCH_MODAL不阻塞事件传递到后面的窗口

// 设置 FLAG_NOT_FOCUSABLE 悬浮窗口较小时,后面的应用图标由不可长按变为可长按

// 不设置这个flag的话,home页的划屏会有问题

params.width = LayoutParams.WRAP_CONTENT;

params.height = LayoutParams.WRAP_CONTENT;

params.gravity = Gravity.TOP;

mWindowManager.addView(mView, params);

}

比较重要的点是要注意设置flags,我这里提供了两种flags以供切换:private static int canTouchFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE

| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;

private static int notTouchFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|

WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;

第一种是可触摸不可聚焦模式,第二种是不可触摸不可聚焦模式。其他的flags可以从api中查阅。

2.设置悬浮框的拖动监听事件:private static View setUpView(final Context context, String showtxt) {

View view = LayoutInflater.from(context).inflate(R.layout.layout_popwindow,

null);

TextView showTv = (TextView) view.findViewById(R.id.tv_showinpop);

showTv.setText(showtxt);

rl_drag_showinpop = (RelativeLayout) view.findViewById(R.id.rl_drag_showinpop);

rl_drag_showinpop.setOnTouchListener(new View.OnTouchListener() {

private float lastX; //上一次位置的X.Y坐标

private float lastY;

private float nowX; //当前移动位置的X.Y坐标

private float nowY;

private float tranX; //悬浮窗移动位置的相对值

private float tranY;

@Override

public boolean onTouch(View v, MotionEvent event) {

boolean ret = false;

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

// 获取按下时的X,Y坐标

lastX = event.getRawX();

lastY = event.getRawY();

ret = true;

break;

case MotionEvent.ACTION_MOVE:

// 获取移动时的X,Y坐标

nowX = event.getRawX();

nowY = event.getRawY();

// 计算XY坐标偏移量

tranX = nowX - lastX;

tranY = nowY - lastY;

params.x += tranX;

params.y += tranY;

//更新悬浮窗位置

mWindowManager.updateViewLayout(mView, params);

//记录当前坐标作为下一次计算的上一次移动的位置坐标

lastX = nowX;

lastY = nowY;

break;

case MotionEvent.ACTION_UP:

break;

}

return ret;

}

});

这里要在down的时候记录坐标,move事件中使用修改params坐标进行移动。

3.设置悬浮框文字属性:public static void setShowTxt(String txt) {

try {

TextView showTv = (TextView) mView.findViewById(R.id.tv_showinpop);

showTv.setText(txt);

mWindowManager.updateViewLayout(mView, params);

}catch (Exception e){

Log.d(TAG, "setShowTxt: 更新悬浮框错误");

e.printStackTrace();

if(e.getMessage().contains("not attached to window manager")){

mWindowManager.addView(mView, params);

}

}

}

4.更新悬浮框图片显示:public static void setShowImg(Bitmap bitmap) {

try {

ImageView showImg = (ImageView) mView.findViewById(R.id.iv_showinpop);

showImg.setImageBitmap(bitmap);

mWindowManager.updateViewLayout(mView, params);

}catch (Exception e){

Log.d(TAG, "setShowTxt: 更新悬浮框错误");

e.printStackTrace();

if(e.getMessage().contains("not attached to window manager")){

mWindowManager.addView(mView, params);

}

}

}

介绍完毕,整个类都封装好了,代码如下:/**

* 悬浮窗工具类

* created by Pumpkin at 17/3/28

*/

public class WindowsUitlity {

private static String TAG = WindowsUitlity.class.getSimpleName();

private static WindowManager mWindowManager = null;

private static WindowManager.LayoutParams params;

public static Boolean isShown = false;

private static View mView = null;

/**

* 显示弹出框

*

* @param context

*/

@SuppressWarnings("WrongConstant")

public static void showPopupWindow(final Context context, String showtxt) {

if (isShown) {

return;

}

isShown = true;

// 获取WindowManager

mWindowManager = (WindowManager) context

.getSystemService(Context.WINDOW_SERVICE);

mView = setUpView(context, showtxt);

params = new WindowManager.LayoutParams();

// 类型,系统提示以及它总是出现在应用程序窗口之上。

params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT |

WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;

// 设置flag

int flags = canTouchFlags;

// | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

// 如果设置了WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,弹出的View收不到Back键的事件

params.flags = flags;

// 不设置这个弹出框的透明遮罩显示为黑色

params.format = PixelFormat.TRANSLUCENT;

// FLAG_NOT_TOUCH_MODAL不阻塞事件传递到后面的窗口

// 设置 FLAG_NOT_FOCUSABLE 悬浮窗口较小时,后面的应用图标由不可长按变为可长按

// 不设置这个flag的话,home页的划屏会有问题

params.width = LayoutParams.WRAP_CONTENT;

params.height = LayoutParams.WRAP_CONTENT;

params.gravity = Gravity.TOP;

mWindowManager.addView(mView, params);

}

private static int canTouchFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE

| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;

private static int notTouchFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|

WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;

/**

* 设置是否可响应点击事件

*

* @param isTouchable

*/

public static void setTouchable(boolean isTouchable) {

if (isTouchable) {

params.flags = canTouchFlags;

} else {

params.flags = notTouchFlags;

}

mWindowManager.updateViewLayout(mView, params);

}

/**

* 隐藏弹出框

*/

public static void hidePopupWindow() {

if (isShown && null != mView) {

mWindowManager.removeView(mView);

isShown = false;

}

}

public static void setShowTxt(String txt) {

try {

TextView showTv = (TextView) mView.findViewById(R.id.tv_showinpop);

showTv.setText(txt);

mWindowManager.updateViewLayout(mView, params);

}catch (Exception e){

Log.d(TAG, "setShowTxt: 更新悬浮框错误");

e.printStackTrace();

if(e.getMessage().contains("not attached to window manager")){

mWindowManager.addView(mView, params);

}

}

}

public static void setShowImg(Bitmap bitmap) {

try {

ImageView showImg = (ImageView) mView.findViewById(R.id.iv_showinpop);

showImg.setImageBitmap(bitmap);

mWindowManager.updateViewLayout(mView, params);

}catch (Exception e){

Log.d(TAG, "setShowTxt: 更新悬浮框错误");

e.printStackTrace();

if(e.getMessage().contains("not attached to window manager")){

mWindowManager.addView(mView, params);

}

}

}

static RelativeLayout rl_drag_showinpop;

private static View setUpView(final Context context, String showtxt) {

View view = LayoutInflater.from(context).inflate(R.layout.layout_popwindow,

null);

TextView showTv = (TextView) view.findViewById(R.id.tv_showinpop);

showTv.setText(showtxt);

rl_drag_showinpop = (RelativeLayout) view.findViewById(R.id.rl_drag_showinpop);

rl_drag_showinpop.setOnTouchListener(new View.OnTouchListener() {

private float lastX; //上一次位置的X.Y坐标

private float lastY;

private float nowX; //当前移动位置的X.Y坐标

private float nowY;

private float tranX; //悬浮窗移动位置的相对值

private float tranY;

@Override

public boolean onTouch(View v, MotionEvent event) {

boolean ret = false;

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

// 获取按下时的X,Y坐标

lastX = event.getRawX();

lastY = event.getRawY();

ret = true;

break;

case MotionEvent.ACTION_MOVE:

// 获取移动时的X,Y坐标

nowX = event.getRawX();

nowY = event.getRawY();

// 计算XY坐标偏移量

tranX = nowX - lastX;

tranY = nowY - lastY;

params.x += tranX;

params.y += tranY;

//更新悬浮窗位置

mWindowManager.updateViewLayout(mView, params);

//记录当前坐标作为下一次计算的上一次移动的位置坐标

lastX = nowX;

lastY = nowY;

break;

case MotionEvent.ACTION_UP:

break;

}

return ret;

}

});

return view;

}

}

看完上述内容,你们对怎么在Android中实现一个自由拖动并显示文字的悬浮框有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注亿速云行业资讯频道,感谢大家的支持。

android 浮动文字提示,怎么在Android中实现一个自由拖动并显示文字的悬浮框相关推荐

  1. vcd文件中存储多维数组 vcs_怎样在Modelsim软件中产生一个.vcd文件并且显示波形?...

    解决方案ID: rd07062010_692 最后修改: 2012 年9 月11 日 产品类别: 设计软件 产品领域: 仿真/一致性验证 产品子领域: ModelSim-Altera(仿真/一致性验证 ...

  2. Android在ListView中嵌套一个GridView时只显示一行的原因及解决方法

    在之前的编程里,我还没有遇到过要在一个ListView中嵌套一个GridView或是在一个GridView中嵌套一个ListView.所以今天事儿来了!我花了一将近3个小时,找到了为什么我在一个Lis ...

  3. android安装apk提示版本号不同,android 安装apk 遇到的问题

    很多应用都是采用内部下载的方式,版本升级后可以实时更新最新应用,这样的体验肯定比跳转到浏览器好得多!而应用商店审核周期长,所以内部下载更新就显得尤为重要! 下面是Android不同版本需要适配安装的问 ...

  4. android file isdirectory,android – 为什么我不能在Environment.DIRECTORY_PICTURES中创建一个目录?...

    这是我的代码 File selfieLocation = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES),"Dail ...

  5. android studio编译提示错误:android Error:(21, 19) 错误: 程序包R不存在

    点击"Build"-->"Clean Project",再次编译没有错误了.针对各种情况而定,这是本人在出现上述报错时,这样就解决问题.这只是作为参考.

  6. android 表格xml,【Android】利用表格布局,Android中xml文件与java的交互制作登录界面...

    登录界面是图形编程.网页编程的一个经典而又基础的程序. 在安卓中,如图所示一个基本登录界面: 点击取消按钮就关闭这个程序,点击登录按钮则显示用户输入的用户名与密码. 一.基本布局 这个程序利用到安卓中 ...

  7. android浮动按钮_Android浮动操作按钮示例教程

    android浮动按钮 Today we will learn about Android Floating Action Button. We'll discuss the FloatingActi ...

  8. android之状态栏提示

    当有未接电话或者短信的时候,android手机上的顶部状态栏就会出现提示. android平台专门提供饿了NotificationManager来管理状态栏信息,提供Notification来处理这些 ...

  9. android wms各个类的作用,Android系统服务 —— WMS

    "可以毫不夸张的说,Android的framework层主要是由WMS.AMS还有View所构成,这三个模块穿插交互在整个framework中,掌握了它们之间的关系和每一个逻辑步骤,你对fr ...

最新文章

  1. 一口气说出 6 种 @Transactional 注解的失效场景
  2. 改写URL的查询字符串QUERY_STRING(转)
  3. Laravel 框架安装
  4. 第三方工具生成密钥对连接GCP服务器(putty生成密钥远程连接服务器)
  5. Python监听剪切板的两种方法
  6. 如何在Cordova Android 7.0.0 以下版本集成最新插件 极光插件为例 1
  7. webview js 与 java 调用参数问题。
  8. git显示服务器所有分支,git 查看所有远程分支以及同步
  9. [react] Consumer向上找不到Provider的时候怎么办?
  10. 三星手机android,个人评测 篇三:三星S10e还值得买吗——半年使用杂谈,最终篇...
  11. efficientNet论文心得
  12. 【前端开发】在windows 10上安装gulp(详细讲解)
  13. 登录学习通报错:浏览器没有开启cookie功能
  14. 数睿数据2022新年致辞:小荷才露尖尖角,早有蜻蜓立上头
  15. localhost不能访问127.0.0.1可以访问的原因及解决方法(整理)
  16. 服务器WPS上的文档删除了怎么办,wps怎么样找回已经删除的文档
  17. 嵌入式软件开发学习 工程师要掌握的基本技能
  18. 手游逆向专题<英雄联盟手游>: Unity内还原亚索渲染效果
  19. 电子商务系统的设计与实现(十一):数据库设计
  20. ubuntu安装ROS时遇到的“由于没有公钥,无法验证签名”问题

热门文章

  1. linux 虚拟一个40段ip,linux – 接口上的Multiples ip地址.我想指定其中一个输出
  2. Java关于延迟加载的一些应用最佳实践
  3. 面试必会之ArrayList源码分析手写ArrayList
  4. linux mysql 备份脚本_linux下mysql备份脚本
  5. php异步处理下载文件,php异步处理-上传文件
  6. Mybatis判断表是否存在
  7. 利用DataSnap的回调功能在客户端显示服务器方法的执行进度
  8. TensorFlow——tf.contrib.layers库中的相关API
  9. GBDT算法之流失预警模型
  10. ActiveMQ专题2: 持久化