[mobilesafe] 03_PopupWindow

Android 4.0

View popupView = View.inflate(getApplicationContext(),R.layout.popup_app_item,null);
ScaleAnimation scaleAnimation = new ScaleAnimation(0.3f,1.1f, 0.3f, 1.1f,
        ScaleAnimation.RELATIVE_TO_SELF,0f, ScaleAnimation.RELATIVE_TO_SELF, 0.7f);
// 缩放前x大小,缩放后x大小,缩放前y大小,缩放后y大小
//起始相对于谁的x位置,起始相对于谁的y位置,结束相对于谁的x位置,结束相对于谁的y位置
scaleAnimation.setDuration(800);
popupView.startAnimation(scaleAnimation);// 下面的一句话是非常重要的 一定要给popwindow设置一个背景颜色
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
核心代码:
// d)注册item的点击事件
lv_app_manage.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view,
            int position, long id) {
        // 参数1:parent,代表当前的ListView
        // 参数2:view,被点击的item,这里是一个相对布局
        // 参数3:position,被点击的item的位置
        // 参数4:id,目前没有用到

        Object obj = parent.getItemAtPosition(position);
        // 注意:返回的Object为null,因为这个要和Adapter一起使用,才会生效。获取的就是getItem(int position)返回的对象

        if (obj != null && obj instanceof AppInfo) {// 如果为null,表示为TextView;不为null,则表示是AppInfo
            AppInfo appInfo = (AppInfo) obj;
            // 1、设置要显示的内容
            String appPackageName = appInfo.getAppPackageName();
            TextView tv = new TextView(getApplicationContext());
            tv.setText(appPackageName);
            tv.setTextColor(Color.RED);
            
            // 2、new出来一个popupwindow
            dismissPopupWindow();

            // int width = LayoutParams.WRAP_CONTENT;// 也可以直接写-2
            // int height = LayoutParams.WRAP_CONTENT;// 也可以直接写-2
            popupWindow = new PopupWindow(tv, -2, -2);// 显示的内容,宽,高
                    popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
            
                     // 3、获取当前组件在窗体上的位置(相对于view对象的左上角)
            int[] location = new int[2];// location[0]:x,location[1]:y
            view.getLocationInWindow(location);
            //获取当前item在屏幕位置(当前item的左上角那一点),the array contains the x and y location in that order
            
            // 4、对齐方式
            int gravity = Gravity.TOP+Gravity.LEFT;//TOP:48  LEFT:3  也可以写53,或者Gravity.TOP|Gravity.LEFT

            // 5、在指定的位置显示出来
            popupWindow.showAtLocation(parent, gravity, 0, location[1]);// 依赖的父窗体,对齐方式,x轴,y轴
        }
    }
}); 结果:
问题1:多次点击条目,出现多个条目,并且拖动时,还不会消失。
解决:
1)出现多个条目,只需要将 popupWindow 设置成成员变量就行了
2)拖动时,还在,设置滚动事件,在滚动的时候销毁之前的popupwindow 
// e)滚动事件
lv_app_manage.setOnScrollListener(new OnScrollListener() {
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        dismissPopupWindow();

        // 在滚动的时候,根据当前显示是用户还是系统应用,来决定在左上角textview显示的是什么
        if (userAppInfos != null && sysAppInfos != null) {//
            if (firstVisibleItem >= (userAppInfos.size() + 1)) {// 到了系统应用显示的位置
                tv_status.setText("系统应用:" + sysAppInfos.size() + "个");
            } else {// 用户应用显示的位置
                tv_status.setText("用户应用:" + userAppInfos.size() + "个");
            }
        }
    }
});
    问题2:点击某个条目,显示位置不对,点击某些条目没有响应
分析:PopupWindow显示的位置为指定的宽度和高度。
问题3:在popupwindow还在显示的时候,按后退键,报了异常
分析:popupwindow绑定的activity泄露了。
解决:在Activity销毁时,会调用onDestroy()方法,所以在这里面销毁popupwindow
@Override
protected void onDestroy() {
    super.onDestroy();
    dismissPopupWindow();// 防止按后退键报popupWindow泄露异常。
}