我们Android平台是一个又一个的Activity组成的,每一个Activity有一个或者多个View构成。所以说,当我们想显示一个界面的时候,我们首先想到的是建立一个Activity,然后所有的操作在Activity里面实现,或者是一个Dialog或者Toast。这种方式固然简单,但是在有些情况下,我们要求的只是简单的显示,用Activity显然是多余,这个时候,我们如何处理呢?
原来,整个Android的窗口机制是基于一个叫做 WindowManager,这个接口可以添加view到屏幕,也可以从屏幕删除view。它面向的对象一端是屏幕,另一端就是View,直接忽略我们以前的Activity或者Dialog之类的东东。其实我们的Activity或者Diolog底层的实现也是通过WindowManager,这个 WindowManager是全局的,整个系统就是这个唯一的东东。它是显示View的最底层了。
一、一个简单WindowManager实例
1 package com.example.qjm3662.simplewindowsmanager; 2 3 import android.graphics.PixelFormat; 4 import android.support.v7.app.AppCompatActivity; 5 import android.os.Bundle; 6 import android.view.WindowManager; 7 import android.widget.TextView; 8 9 public class MainActivity extends AppCompatActivity { 10 11 WindowManager wManager; 12 @Override 13 protected void onCreate(Bundle savedInstanceState) { 14 super.onCreate(savedInstanceState); 15 setContentView(R.layout.activity_main); 16 17 //Activity自带一个getWindowManager()方法,可以获得当前系统的WindowManager 18 wManager = getWindowManager(); 19 TextView tv = new TextView(this); 20 tv.setText("sdgvsd"); 21 //布局参数 22 WindowManager.LayoutParams params = new WindowManager.LayoutParams(); 23 params.width = 200; 24 params.height = 200; 25 26 //设置透明程度 27 params.format = PixelFormat.TRANSPARENT; 28 //params.format = PixelFormat.RGBA_8888; 29 //设置是否获得焦点,如果获得焦点,则底层的View无法获得焦点,也无法响应返回键,默认是获得 30 params.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; 31 wManager.addView(tv,params); 32 } 33 }
二、WindowManager的属性(WindowManager.LayoutParms)
详细的属性表在:
http://www.cnblogs.com/shitianzeng/articles/2814050.html
三、如何让一个view显示在桌面(即Activity销毁后(或在后台)仍可在桌面显示指定view)---》eg:各种安全软件的悬浮球
----》利用Service
1 package com.example.qjm3662.windowmanager; 2 3 import android.content.Intent; 4 import android.os.Bundle; 5 import android.support.v7.app.AppCompatActivity; 6 import android.view.Menu; 7 import android.view.MenuItem; 8 import android.view.View; 9 import android.widget.Button; 10 11 public class MainActivity extends AppCompatActivity { 12 13 Button button; 14 @Override 15 protected void onCreate(Bundle savedInstanceState) { 16 super.onCreate(savedInstanceState); 17 setContentView(R.layout.activity_main); 18 19 button = (Button) findViewById(R.id.btn_start); 20 button.setOnClickListener(new View.OnClickListener() { 21 @Override 22 public void onClick(View v) { 23 startService(new Intent(MainActivity.this,WindowManagerService.class)); 24 } 25 }); 26 } 27 28 @Override 29 public boolean onCreateOptionsMenu(Menu menu) { 30 getMenuInflater().inflate(R.menu.menu_main,menu); 31 return true; 32 } 33 34 @Override 35 public boolean onOptionsItemSelected(MenuItem item) { 36 int id = item.getItemId(); 37 38 if(id == R.id.action_settings){ 39 return true; 40 } 41 return super.onOptionsItemSelected(item); 42 } 43 }
package com.example.qjm3662.windowmanager; import android.app.Service; import android.content.Context; import android.content.Intent; import android.graphics.PixelFormat; import android.os.Handler; import android.os.IBinder; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; import android.widget.TextView; public class WindowManagerService extends Service { private Handler handler = new Handler(); public WindowManagerService() { } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { String msg = "This is a text message"; final WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); final View view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.view_system,null); TextView tv = (TextView) view.findViewById(R.id.tv); tv.setText(msg); final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.x = 0; params.y = 0; params.gravity = Gravity.RIGHT | Gravity.BOTTOM; params.width = 400; params.height = 400; params.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; params.format = PixelFormat.TRANSPARENT; params.flags |= WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN; wm.addView(view,params); new Thread(){ @Override public void run() { super.run(); try { Thread.sleep(15000); handler.post(new Runnable() { @Override public void run() { wm.removeViewImmediate(view); } }); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); return super.onStartCommand(intent, flags, startId); } }