WindowManager的分析
一、Window和WindowManager
Window:表示一个窗口,从下面Window的源码中可以看出它有且只有一个实现类PhoneWindow。
The only existing implementation of this abstract class is * android.policy.PhoneWindow, which you should instantiate when needing a * Window.WindowManager:它是系统提供我们操作Window的一个接口,我们可以通过WindowManage提供的方法对window进行添加、修改、删除等操作。一般有View的地方都有window。
二、Window在事件分发中的应用当一个点击事件产生时,它首先传递到Activity、在Activity的dispatchToucheEvent的方法中进行分发、然后传递到Window、最后才到顶级view。看源码:
public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { onUserInteraction(); } if (getWindow().superDispatchTouchEvent(ev)) { return true; } return onTouchEvent(ev); }由于window只有一个实现类,所以查看PhoneWindow的源码。
@Override public boolean superDispatchTouchEvent(MotionEvent event) { return mDecor.superDispatchTouchEvent(event); }而这里的mDecor就是顶级View,就这样事件就从window传递到了顶级View了。
三、创建Window的快速入门运行截图
由于Toast的源码也是通过添加window实现的,只不过使用了handler而已,因此这里我们参照Toast来简单实现
xml文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="创建Window" /> </LinearLayout>java代码
super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button) findViewById(R.id.btn); button = new Button(this); button.setText("我是Window"); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Toast.makeText(getApplicationContext(), "我是被Window按钮点击的", 0).show(); } }) ; btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mWM = (WindowManager)getSystemService(Context.WINDOW_SERVICE); mParams = new WindowManager.LayoutParams(); // XXX This should be changed to use a Dialog, with a Theme.Toast // defined that sets up the layout params appropriately. final WindowManager.LayoutParams params = mParams; params.height = WindowManager.LayoutParams.WRAP_CONTENT; params.width = WindowManager.LayoutParams.WRAP_CONTENT; params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON // | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE ; params.format = PixelFormat.TRANSLUCENT; //设置这个flag可以将被添加按钮有点击事件 params.type = WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING; params.setTitle("Toast"); mWM.addView(button, mParams) ; } });简单说明下:上面的代码大部分是我从Toast的源码中赋值下来的,不过为了让显示的Toast有点击效果,做了小小的修改,上面已经做了注释。
四、Toast创建的源码分析首先查看Toast的makeText()方法
public static Toast makeText(Context context, CharSequence text, int duration) { Toast result = new Toast(context); LayoutInflater inflate = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null); TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message); tv.setText(text); result.mNextView = v; result.mDuration = duration; return result; }温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/61869.html