您的位置:首页 > 移动开发 > Android开发

Android应用Activity、Dialog、PopWindow、Toast窗口添加机制及源码分析 《二》

2015-07-14 15:36 746 查看
转载:http://blog.csdn.net/yanbober/article/details/46361191

上篇文章简要分析了 Window 的源码 ,这边文章结合实际开发代码分析:

Part1:开发APP时设置Activity全屏常亮的一种办法(设置Activity也就是Activity的Window):

public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置Activity的Window为全屏,当然也可以在xml中设置
Window window = getWindow();
WindowManager.LayoutParams windowAttributes = window.getAttributes();
windowAttributes.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN | windowAttributes.flags;
window.setAttributes(windowAttributes);
//设置Activity的Window为保持屏幕亮
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

setContentView(R.layout.activity_main);
}
}


这是运行结果:



Part2:App开发中弹出软键盘时下面的输入框被软件盘挡住问题的解决办法:

在Activity中的onCreate中setContentView之前写如下代码:

//你也可以在xml文件中设置,一样的效果
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE|WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);


Part3:创建悬浮窗口(仿IPhone的小圆点或者魅族的小白点或者360手机卫士的小浮标),退出当前Activity依旧可见的一种实现方法:

省略了Activity的start与stop Service的按钮代码,直接给出了核心代码如下:

/**
* Author       : yanbo
* Time         : 14:47
* Description  : 手机屏幕悬浮窗,仿IPhone小圆点
*               (未完全实现,只提供思路,如需请自行实现)
* Notice       : <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
*/
public class WindowService extends Service {
private WindowManager mWindowManager;
private ImageView mImageView;

@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public void onCreate() {
super.onCreate();
//创建悬浮窗
createFloatWindow();
}

private void createFloatWindow() {
//这里的参数设置上面刚刚讲过,不再说明
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
mWindowManager = (WindowManager) getApplication().getSystemService(Context.WINDOW_SERVICE);
//设置window的type
layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
//设置效果为背景透明
layoutParams.format = PixelFormat.RGBA_8888;
//设置浮动窗口不可聚焦
layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
layoutParams.gravity = Gravity.BOTTOM | Gravity.RIGHT;
layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
layoutParams.x = -50;
layoutParams.y = -50;

mImageView = new ImageView(this);
mImageView.setImageResource(android.R.drawable.ic_menu_add);
//添加到Window
mWindowManager.addView(mImageView, layoutParams);
//设置监听
mImageView.setOnTouchListener(touchListener);
}

@Override
public void onDestroy() {
super.onDestroy();
if (mImageView != null) {
//讲WindowManager时说过,add,remove成对出现,所以需要remove
mWindowManager.removeView(mImageView);
}
}

private View.OnTouchListener touchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//模拟触摸触发的事件
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
return false;
}
};
}


如下是运行过程模拟,特别留意屏幕右下角的变化:



2-5 总结Activity的窗口添加机制

有了上面这么多分析和前几篇的分析,我们对Activity的窗口加载再次深入分析总结如下:



可以看见Context的WindowManager对每个APP来说是一个全局单例的,而Activity的WindowManager是每个Activity都会新创建一个的(其实你从上面分析的两个实例化WindowManagerImpl的构造函数参数传递就可以看出来,Activity中Window的WindowManager成员在构造实例化时传入给WindowManagerImpl中mParentWindow成员的是当前Window对象,而ContextImpl的static块中单例实例化WindowManagerImpl时传入给WindowManagerImpl中mParentWindow成员的是null值),所以上面模拟苹果浮动小图标使用了Application的WindowManager而不是Activity的,原因就在于这里;使用Activity的WindowManager时当Activity结束时WindowManager就无效了,所以使用Activity的getSysytemService(WINDOW_SERVICE)获取的是Local的WindowManager。同时可以看出来Activity中的WindowManager.LayoutParams的type为TYPE_APPLICATION。

好了,上面也说了不少了,有了上面这些知识点以后我们就来开始分析Android应用Activity、Dialog、PopWindow窗口显示机制。

【工匠若水 http://blog.csdn.net/yanbober 转载烦请注明出处,尊重劳动成果】
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息