35、程序管理器--显示卸载、启动、分享的PopupWindow代码实现

在AppManagerActivity中为listview设置item的点击事件:

lv_apps.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                //当用户点击下一个Item时,需要关闭已经存在的PopupWindow
                dismissPopupWindow();
                //将布局文件转成view,该view用于显示PopupWindow中的内容
                View contentView = View.inflate(getApplicationContext(),R.layout.popup_item, null);
                //分别获取到PopupWindow窗体中的"卸载、启动、分享"控件所对应的父控件
                ll_uninstall = (LinearLayout) contentView.findViewById(R.id.ll_popup_uninstall);
                ll_start = (LinearLayout) contentView.findViewById(R.id.ll_popup_start);
                ll_share = (LinearLayout) contentView.findViewById(R.id.ll_popup_share);
                //获取用于显示PopupWindow内容的View的根布局,这里是要为该布局设置动画(相当于为PopupWindow设置动画)
                View ll_popup_container = contentView.findViewById(R.id.ll_popup_container);

                //为"卸载、启动、分享"设置点击事件
                ll_share.setOnClickListener(AppManagerActivity.this);
                ll_start.setOnClickListener(AppManagerActivity.this);
                ll_uninstall.setOnClickListener(AppManagerActivity.this);

                //获取到当前Item的对象
                Object obj = lv_apps.getItemAtPosition(i);
                //当Item为系统应用时,此时为PopupWindow中的"卸载"设置一个标记,在卸载时判断该标记,禁止卸载系统应用
                if (obj instanceof AppInfo) {
                    AppInfo appinfo = (AppInfo) obj;
                    clickedpackname = appinfo.getPackname();
                    if (appinfo.isUserpp()) {
                        ll_uninstall.setTag(true);
                    } else {
                        ll_uninstall.setTag(false);
                    }
                } else {
                    return;
                }
                //获取到当前Item离顶部、底部的距离
                int top = view.getTop();
                int bottom = view.getBottom();
                //创建PopupWindow窗体时必须要指定窗体的大小,否则不会显示在界面上。参数一:窗体中用于显示内容的viewContent,参数二、三:表示PopupWindow窗体的宽和高
                popupWindow = new PopupWindow(contentView, DensityUtil.dip2px(getApplicationContext(), 200), bottom - top
                        + DensityUtil.dip2px(getApplicationContext(), 30));
                // 注意:一定要给popwindow设置背景图片或背景资源,如果不设置背景资源 , 动画、 焦点的处理 都会产生问题。
                popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
                //获取到Item在窗体中显示的位置
                int[] location = new int[2];
                view.getLocationInWindow(location);
                //参数一:PopupWindow挂载在那个View上,参数二:设置PopupWindow显示的重心位置
                //参数三:PopupWindow在View上X轴的偏移量,参数四:PopupWindow在View上Y轴的偏移量。X、Y轴的偏移量是相对于当前Activity所在的窗体,参照点为(0,0)
                popupWindow.showAtLocation(view, Gravity.TOP | Gravity.LEFT, location[0] + 20, location[1]);

                //设置一个缩放的动画效果
                ScaleAnimation sa = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f);
                //设置动画执行的时间
                sa.setDuration(300);
                // 播放一个缩放的动画.
                ll_popup_container.startAnimation(sa);
            }
        });
单击item时,如果之前有弹出窗口则调用dismissPopupWindow关闭,将上文设计的布局文件转换为view,并获取相应控件。

为"卸载、启动、分享"设置点击事件,为父窗口的显示设置一个动画渐进效果,效果为从左上角300毫秒渐出。

getItemAtPosition获取listview所在位置的对象,如果是应用程序信息再判断是否是系统程序,因为系统程序不可卸载。

后面就是在指定的位置显示出PopupWindow。


dismissPopupWindow的实现:

    private void dismissPopupWindow() {
        if (popupWindow != null && popupWindow.isShowing()) {
            popupWindow.dismiss();
            popupWindow = null;
        }
    }
在activity的onDestroy中也调用了dismissPopupWindow:

    @Override
    protected void onDestroy() {
        dismissPopupWindow();
        super.onDestroy();
    }

另外点击listview的两个分组时,不应该弹出PopupWindow,可以设置这两个item为禁用的,重载BaseAdapter的isEnabled:

        /**
         * 屏蔽掉两个TextView(用户程序和系统程序)被点击时的焦点
         */
        @Override
        public boolean isEnabled(int position) {
            if (position == 0 || position == (userappInfos.size() + 1)) {
                return false;
            }
            return super.isEnabled(position);
        }

当用户滑动窗体的时候,需要关闭已经存在的PopupWindow:

/**
         * 当用户滑动窗体的时候,需要关闭已经存在的PopupWindow
         */
        lv_apps.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView absListView, int i) {
            }

            @Override
            public void onScroll(AbsListView absListView, int i, int i2, int i3) {
                dismissPopupWindow();
            }
        });

其中用到的DensityUtil的代码:

package com.example.utils;

import android.content.Context;

public class DensityUtil {
    /** 
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素) 
     */  
    public static int dip2px(Context context, float dpValue) {  
        final float scale = context.getResources().getDisplayMetrics().density;  
        return (int) (dpValue * scale + 0.5f);  
    }  
  
    /** 
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp 
     */  
    public static int px2dip(Context context, float pxValue) {  
        final float scale = context.getResources().getDisplayMetrics().density;  
        return (int) (pxValue / scale + 0.5f);  
    }  
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

asmcvc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值