WindowManager简介
WindowManager
是Android系统中的一个核心类,它负责管理窗口的创建、显示、位置和大小等。WindowManager
通常用于创建浮动窗口、自定义窗口布局或管理系统的顶级窗口。
WindowManager的作用
- 创建窗口:可以在屏幕上创建额外的窗口,这些窗口可以是浮动的、半透明的或具有特定的尺寸和位置。
- 管理窗口布局:可以更改窗口的位置、大小和布局属性。
- 管理屏幕方向:可以获取屏幕的方向信息,并据此调整窗口的布局。
- 处理输入事件:可以处理窗口接收到的触摸和其他输入事件。
使用场景
- 浮动窗口:例如,实现悬浮球、悬浮菜单等功能。
- 自定义布局:例如,创建自定义的登录界面或对话框。
- 屏幕截图:例如,截取屏幕的一部分。
- 屏幕方向管理:例如,根据屏幕方向调整布局。
使用WindowManager
创建一个浮动窗口
import android.app.Activity;
import android.content.Context;
import android.graphics.PixelFormat;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
public class FloatingWindowActivity extends Activity {
private WindowManager windowManager;
private View floatingView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 获取WindowManager服务
windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
// 创建浮动窗口的布局
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
layout.setOrientation(LinearLayout.VERTICAL);
layout.setBackgroundColor(0x80FFFFFF); // 设置背景颜色
// 创建一个按钮
Button button = new Button(this);
button.setText("Click me!");
layout.addView(button);
// 设置浮动窗口的参数
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
// 设置初始位置
params.gravity = Gravity.CENTER;
params.x = 0;
params.y = 0;
// 添加浮动窗口
floatingView = layout;
windowManager.addView(floatingView, params);
// 处理点击事件
button.setOnClickListener(v -> {
// 移动窗口
params.x += 100;
params.y += 100;
windowManager.updateViewLayout(floatingView, params);
});
// 处理触摸事件
floatingView.setOnTouchListener((v, event) -> {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 获取手指按下时的位置
params.x = (int) event.getRawX();
params.y = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
// 更新位置
params.x = (int) event.getRawX() - (int) event.getX();
params.y = (int) event.getRawY() - (int) event.getY();
windowManager.updateViewLayout(floatingView, params);
break;
}
return true;
});
}
}
获取WindowManager服务:
- 使用
getSystemService(Context.WINDOW_SERVICE)
获取WindowManager
服务。
- 使用
创建浮动窗口的布局:
- 创建一个
LinearLayout
作为浮动窗口的布局,并添加一个Button
。 - 设置背景颜色和布局参数。
- 创建一个
设置窗口参数:
- 创建一个
WindowManager.LayoutParams
对象,并设置窗口的类型、标志、格式等。 - 设置初始位置为屏幕中心。
- 创建一个
添加窗口:
- 使用
windowManager.addView()
将浮动窗口添加到屏幕上。
- 使用
处理点击事件:
- 为
Button
设置点击监听器,点击时移动窗口的位置。
- 为
处理触摸事件:
- 为浮动窗口设置触摸监听器,实现窗口的拖动。
使用WindowManager实现屏幕方向管理
在Android中,WindowManager
主要用于管理窗口的创建和布局,但它并不直接负责屏幕方向的管理。屏幕方向通常是通过Activity
或Fragment
的配置来自动处理的。然而,如果你想在WindowManager
创建的自定义窗口中根据屏幕方向调整布局,可以通过以下步骤实现:
- 获取屏幕方向:使用
Display
类来获取当前屏幕的方向。 - 根据方向调整布局:根据获取的方向动态调整窗口的布局参数。
使用WindowManager
根据屏幕方向调整窗口的位置
import android.app.Activity;
import android.content.Context;
import android.graphics.Point;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
public class ScreenOrientationActivity extends Activity {
private WindowManager windowManager;
private View floatingView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 获取WindowManager服务
windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
// 创建浮动窗口的布局
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
layout.setOrientation(LinearLayout.VERTICAL);
layout.setBackgroundColor(0x80FFFFFF); // 设置背景颜色
// 创建一个按钮
Button button = new Button(this);
button.setText("Click me!");
layout.addView(button);
// 获取屏幕尺寸
Display display = windowManager.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int screenWidth = size.x;
int screenHeight = size.y;
// 获取屏幕方向
int orientation = getResources().getConfiguration().orientation;
// 根据屏幕方向设置窗口参数
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
// 设置初始位置
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
// 横屏
params.gravity = Gravity.CENTER;
params.x = 0;
params.y = 0;
} else {
// 竖屏
params.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
params.x = 0;
params.y = 0;
}
// 添加浮动窗口
floatingView = layout;
windowManager.addView(floatingView, params);
// 处理点击事件
button.setOnClickListener(v -> {
// 移动窗口
params.x += 100;
params.y += 100;
windowManager.updateViewLayout(floatingView, params);
});
// 监听屏幕方向变化
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
display.addCallback(new Display.OnDisplayChangeListener() {
@Override
public void onDisplayChanged(Display display) {
int newOrientation = getResources().getConfiguration().orientation;
if (newOrientation != orientation) {
orientation = newOrientation;
// 根据新的屏幕方向调整窗口位置
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
// 横屏
params.gravity = Gravity.CENTER;
params.x = 0;
params.y = 0;
} else {
// 竖屏
params.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
params.x = 0;
params.y = 0;
}
windowManager.updateViewLayout(floatingView, params);
}
}
});
}
}
获取屏幕尺寸:
- 使用
Display.getSize(Point)
方法获取屏幕的宽度和高度。
- 使用
获取屏幕方向:
- 使用
getResources().getConfiguration().orientation
获取当前屏幕的方向。
- 使用
设置窗口参数:
- 根据屏幕方向设置窗口的初始位置。
- 对于横屏模式,将窗口居中显示。
- 对于竖屏模式,将窗口放置在顶部中央。
监听屏幕方向变化:
- 使用
Display.addCallback()
方法注册一个监听器,当屏幕方向改变时更新窗口的位置。
- 使用
处理点击事件:
- 为
Button
设置点击监听器,点击时移动窗口的位置。
- 为