一、悬浮窗基础
悬浮窗是属于Android系统的一种浮动窗口,可以在其他应用程序的上层显示,可以随意拖动、缩放、关闭等操作,常用于提醒、通知、广告等。本节将着重介绍悬浮窗的基本概念和使用方法。
1.1 悬浮窗的基本构成
在Android系统中,每个窗口都对应一个Window对象,而悬浮窗就是一种特殊的Window,通常采用从系统层面抽象出的ViewSystem中的PopupWindow来实现。
其中,PopupWindow是继承自具有运动能力的WindowManager.LayoutParams的一个类,这也意味着我们可以随意对其进行位置、大小、显示方式等操作。因此,我们可以使用PopupWindow实现一个不影响其他应用可随意操作且不需要Activity跳转的自定义悬浮窗。
1.2 悬浮窗的实现方法
实现一个悬浮窗分为以下几个步骤:
(1)在AndroidManifest.xml中声明悬浮窗权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
(2)在需要显示悬浮窗的Activity或Service里面创建WindowManager和PopupWindow,设置其显示位置、大小和内容等属性
//创建布局
View layout = View.inflate(this, R.layout.float_window, null);
//创建管理器
WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
//创建悬浮窗
PopupWindow mPopupWindow = new PopupWindow(layout,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT);
//设置显示位置
mPopupWindow.showAtLocation(parentView, Gravity.LEFT | Gravity.TOP, x, y);
//设置可点击和可获取焦点
mPopupWindow.setTouchable(true);
mPopupWindow.setFocusable(true);
//设置背景色
mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
(3)设置悬浮窗布局内控件的点击事件、拖拽监听事件等
layout.findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(FloatWindowActivity.this, "You clicked button1", Toast.LENGTH_SHORT).show();
}
});
mPopupWindow.setOnTouchListener(new View.OnTouchListener() {
int lastX, lastY;
int paramX, paramY;
@Override
public boolean onTouch(View v, MotionEvent event) {
//获取当前触摸点相对于屏幕的坐标
int x = (int) event.getRawX();
int y = (int) event.getRawY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = x;
lastY = y;
paramX = mPopupWindow.getLayoutParams().x;
paramY = mPopupWindow.getLayoutParams().y;
break;
case MotionEvent.ACTION_MOVE:
int dx = x - lastX;
int dy = y - lastY;
mPopupWindow.update(paramX + dx, paramY + dy, -1, -1);
break;
}
return false;
}
});
二、悬浮窗应用场景与实现技巧
悬浮窗可以提供多种便利的功能和交互操作,因此在实际应用中有广泛的应用场景,常见的有:
2.1 悬浮窗提醒
悬浮窗可以在用户浏览其他应用时,提醒用户即时更新消息,如即时通讯软件的新消息提醒。
2.2 悬浮窗广告
悬浮窗可以向用户展示信息,可以作为一种广告展示方式出现在App中。
2.3 悬浮窗控制
悬浮窗可以设置在屏幕顶部或底部,方便用户随时控制应用的运行和停止,如音乐播放器的播放控制。
2.4 悬浮窗显示技巧
在实际开发过程中,可以通过以下方式优化悬浮窗的用户体验:
(1)悬浮窗自适应
在不同屏幕分辨率和设备角度下,悬浮窗需要能够自适应大小或宽高比,提升用户体验;
(2)悬浮窗延时
为避免误操作和用户视觉干扰,可以设置延时显示或延时关闭功能;
(3)悬浮窗透明度
悬浮窗可以设置透明度或背景色,适配不同的主题和App风格;
(4)悬浮窗关闭方法
悬浮窗需要设置方便关闭的方法,例如双击、四指缩小等。
三、悬浮窗实例
下面给出一个简单的悬浮窗实例:
首先,在AndroidManifest.xml中添加悬浮窗权限声明:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
然后,在MainActivity中添加以下代码:
private void showFloatWindow() {
//创建布局
View layout = View.inflate(this, R.layout.float_window, null);
//创建管理器
WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
//获取屏幕宽高以及状态栏高度
DisplayMetrics dm = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dm);
int screenWidth = dm.widthPixels;
int screenHeight = dm.heightPixels;
int statusBarHeight = getStatusBarHeight(this);
//创建悬浮窗
PopupWindow mPopupWindow = new PopupWindow(layout,
(int) (screenWidth * 0.8),
(int) (screenHeight * 0.8));
//设置显示位置
mPopupWindow.showAtLocation(findViewById(R.id.main_view), Gravity.TOP,
(int) (screenWidth * 0.1),
(int) (statusBarHeight + screenHeight * 0.2));
//设置可点击和可获取焦点
mPopupWindow.setTouchable(true);
mPopupWindow.setFocusable(true);
//设置背景色
mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
//设置关闭方法
layout.findViewById(R.id.close).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mPopupWindow.dismiss();
}
});
}
//获取状态栏高度
public int getStatusBarHeight(Context context) {
int statusBarHeight = 0;
Resources res = context.getResources();
int resourceId = res.getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
statusBarHeight = res.getDimensionPixelSize(resourceId);
}
return statusBarHeight;
}
layout.xml布局文件如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="200dp"
android:background="#66000000">
<TextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#ffffff"
android:layout_marginTop="48dp"
android:textSize="20sp"
android:text="这是一条悬浮窗信息"/>
<Button
android:id="@+id/close"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@mipmap/ic_launcher"
android:layout_alignParentRight="true"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp"/>
</RelativeLayout>
运行效果如下图所示:
最新评论