iapp悬浮记事本源码_iapp跳转开启悬浮窗源码

第三方分享代码
hacker 2年前 (2022-07-22) 数据库 14 5

项目中需要实现一个状态显示的悬浮框,要求可以设置两种模式:拖动模式和不可拖动模式。

实现效果图如下:

实现步骤:

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

/**

* 显示弹出框

*

* @param context

*/

@SuppressWarnings("WrongConstant")

publicstaticvoidshowPopupWindow(finalContext context, String showtxt) {

if(isShown) {

return;

}

isShown = true;

// 获取WindowManager

mWindowManager = (WindowManager) context

展开全文

.getSystemService(Context.WINDOW_SERVICE);

mView = setUpView(context, showtxt);

params = newWindowManager.LayoutParams();

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

params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT |

WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;

// 设置flag

intflags = 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以供切换:

privatestaticintcanTouchFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE

| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;

privatestaticintnotTouchFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|

WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;

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

2、设置悬浮框的拖动监听事件:

privatestaticView setUpView(finalContext 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(newView.OnTouchListener() {

privatefloatlastX; //上一次位置的X.Y坐标

privatefloatlastY;

privatefloatnowX; //当前移动位置的X.Y坐标

privatefloatnowY;

privatefloattranX; //悬浮窗移动位置的相对值

privatefloattranY;

@Override

publicbooleanonTouch(View v, MotionEvent event) {

booleanret = false;

switch(event.getAction()) {

caseMotionEvent.ACTION_DOWN:

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

lastX = event.getRawX();

lastY = event.getRawY();

ret = true;

break;

caseMotionEvent.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;

caseMotionEvent.ACTION_UP:

break;

}

returnret;

}

});

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

3、设置悬浮框文字属性:

publicstaticvoidsetShowTxt(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、更新悬浮框图片显示:

publicstaticvoidsetShowImg(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

*/

publicclassWindowsUitlity {

privatestaticString TAG = WindowsUitlity.class.getSimpleName();

privatestaticWindowManager mWindowManager = null;

privatestaticWindowManager.LayoutParams params;

publicstaticBoolean isShown = false;

privatestaticView mView = null;

/**

* 显示弹出框

*

* @param context

*/

@SuppressWarnings("WrongConstant")

publicstaticvoidshowPopupWindow(finalContext context, String showtxt) {

if(isShown) {

return;

}

isShown = true;

// 获取WindowManager

mWindowManager = (WindowManager) context

.getSystemService(Context.WINDOW_SERVICE);

mView = setUpView(context, showtxt);

params = newWindowManager.LayoutParams();

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

params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT |

WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;

iapp悬浮记事本源码_iapp跳转开启悬浮窗源码

// 设置flag

intflags = 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);

}

privatestaticintcanTouchFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE

| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;

privatestaticintnotTouchFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|

iapp悬浮记事本源码_iapp跳转开启悬浮窗源码

WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;

/**

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

*

* @param isTouchable

*/

publicstaticvoidsetTouchable(booleanisTouchable) {

if(isTouchable) {

params.flags = canTouchFlags;

} else{

params.flags = notTouchFlags;

}

mWindowManager.updateViewLayout(mView, params);

}

/**

* 隐藏弹出框

*/

publicstaticvoidhidePopupWindow() {

if(isShown && null!= mView) {

mWindowManager.removeView(mView);

isShown = false;

}

}

publicstaticvoidsetShowTxt(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);

}

}

}

publicstaticvoidsetShowImg(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);

}

}

}

staticRelativeLayout rl_drag_showinpop;

privatestaticView setUpView(finalContext 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(newView.OnTouchListener() {

privatefloatlastX; //上一次位置的X.Y坐标

privatefloatlastY;

privatefloatnowX; //当前移动位置的X.Y坐标

privatefloatnowY;

privatefloattranX; //悬浮窗移动位置的相对值

privatefloattranY;

@Override

publicbooleanonTouch(View v, MotionEvent event) {

booleanret = false;

switch(event.getAction()) {

caseMotionEvent.ACTION_DOWN:

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

lastX = event.getRawX();

lastY = event.getRawY();

ret = true;

break;

caseMotionEvent.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;

caseMotionEvent.ACTION_UP:

break;

}

returnret;

}

});

returnview;

}

}

头条新闻

尚学堂每周有免费的试听课程,

想学习的同学们,可以先来试听。

参加试听方法:点击阅读原文,提交姓名+电话,课程老师给同学们安排座位,免费试学Java前端课程。

www.029sxt.com

相关推荐

网友评论

  • (*)

最新评论

  • 访客 2022-07-22 20:28:13 回复

    indowManager.updateViewLayout(mView, params); }catch(Exception e){ Log.d(TAG, "setShowTxt: 更新悬浮框错误"); e.printStackT

    1
  • 访客 2022-07-23 00:22:53 回复

    returnview; } } 头条新闻▼尚学堂每周有免费的试听课程,想学习的同学们,可以先来试听。参加试听方法:点击阅读原文,提交姓名+电话,课程老师给同学们安排座位,免费试学Java前端课程。www.029sxt.com

    2
  • 访客 2022-07-23 00:37:42 回复

    ble*/publicstaticvoidsetTouchable(booleanisTouchable) { if(isTouchable) { params.f

    3
  • 访客 2022-07-22 19:21:10 回复

    showTv.setText(txt); mWindowManager.updateViewLayout(mView, params); }catch(Exception e){ Log.d(TAG, "setShowTxt: 更新悬浮框

    4
  • 访客 2022-07-22 22:51:05 回复

    wManager mWindowManager = null; privatestaticWindowManager.LayoutParams params; publicsta

    5