#简介
- Android提供的一个
系统服务——WindowManager(窗口管理服务), 是显示View的最底层! WindowManagerAndroid为我们提供的用于与窗口管理器进行交互的一个API;
- 我们知道**`App的界面`都是 由`Acitivty`组成, 而`Activity`又由`View`组成, 当我们想显示一个`界面`的时候, 可能首先想到`Activity`,又或者是`Dialog`和`Toast`。** - 但是有些情况下, `Activity、Dialog、Toast`可能`满足不了`我们的`需求`, 比如, 仅要做一个`简单的显示`的话 用`Activity`显得有点`多余`了, 而`Dialog`又需要`Context`对象, `Toast`又不可以点击; - **对于以上情况, 我们便可以用`WindowManager`来`添加View`到`屏幕上`, 或者从屏幕上`移除View`! 它就是`管理Android窗口机制`的一个`接口`, `显示View`的`最底层`!**
-
Toast,Activity,Dialog的底层都用到了WindowManager, -
WindowManager是全局的! -
该类的
核心:- 调用
addView,removeView,updateViewLayout等方法 来显示View - 通过
WindowManager.LayoutParams这个API来设置相关的属性
- 调用
#使用
①获得WindowManager对象:
WindowManager wManager = getApplicationContext().getSystemService(Context. WINDOW_ SERVICE);
②获得WindowManager.LayoutParams对象,为后续操作做准备
WindowManager.LayoutParams wmParams=new WindowManager.LayoutParams();
###使用实例: #####实例1:获取屏幕宽高 在Android 4.2前,用下述方法获得屏幕宽高:
public static int[] getScreenHW(Context context) {
WindowManager manager = (WindowManager)context
.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
int[] HW = new int[] { width, height };
return HW;
}
而上述的方法在Android 4.2以后就过时了,之后该用另一种方法获得屏幕宽高:
public static int[] getScreenHW2(Context context) {
WindowManager manager = (WindowManager) context.
getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels;
int height = dm.heightPixels;
int[] HW = new int[] { width, height };
return HW;
}
然后可以再另外写两个获取宽以及高的方法, 这里以第二种获得屏幕宽高为例:
public static int getScreenW(Context context) {
return getScreenHW2(context)[0];
}
public static int getScreenH(Context context) {
return getScreenHW2(context)[1];
}
开始时候可以将以上代码封装成工具类;
或者直接直接获取:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WindowManager wManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
wManager.getDefaultDisplay().getMetrics(dm);
Toast.makeText(MainActivity.this, "当前手机的屏幕宽高:" + dm.widthPixels + "*" +
dm.heightPixels, Toast.LENGTH_SHORT).show();
}
}
public class MainActivity extends AppCompatActivity {
private TextView tv_test;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_test = findViewById(R.id.tv_test);
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024 / 1024);
DisplayMetrics outMetrics = new DisplayMetrics();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
getWindowManager().getDefaultDisplay().getRealMetrics(outMetrics);
}
int widthPixel = outMetrics.widthPixels;
int heightPixel = outMetrics.heightPixels;
String text = "最大运行内存是 " + maxMemory + "M" + "\n";
text += "屏宽 = " + widthPixel + "像素, 屏高 = " + heightPixel + "像素";
tv_test.setText(text);
}
}
####实例2:设置窗口全屏显示
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
getSupportActionBar().hide();
#####实例3:保持屏幕常亮
public void setKeepScreenOn(Activity activity,boolean keepScreenOn)
{
if(keepScreenOn)
{
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}else{
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
#Window与WindowManager
-
Window表示一个窗口的概念, 在日常开发中直接接触Window的机会并不多, 但是在某些特殊时候 需要在桌面上显示一个类似
悬浮窗的东西, 这种效果就需要用Window实现。 -
Window是一个抽象类,它的具体实现是PhoneWindow。 -
创建一个Window是很简单的事, 只需要通过WindowManager即可完成。 -
WindowManager是外界访问Window的入口,Window的具体实现位于WindowManagerService中,WindowManager和WindowManagerService的交互是一个IPC过程。 -
Android中
所有的视图都是通过Window来呈现的, 不管是Activity、Dialog还是Toast, 它们的视图实际上都是附加在Window上的, 因此Window实际是View的直接管理者。
从View的事件分发机制也可以知道,
单击事件由Window传递给DecorView,
然后再由DecorView传递给我们的View,
就连Activity的设置视图的方法setContentView在底层也是通过Window来完成的。