Windowmanager使用

本文介绍了如何在Android中利用WindowManager实现应用外弹屏或悬浮窗,并详细探讨了不同手机型号下悬浮窗的行为差异及解决方案。文中还分享了具体的代码实现细节。

一、WindowManger可以用于应用外弹屏或悬浮窗360手机卫士的弹窗印象深刻
首先需要系统权限

  <!-- 悬浮窗的显示 -->
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

二、在维护一个刚接手的项目时,发现有的手机像SUMSUNG,LENOVO,按home键 悬浮窗就会随应用消失, 为了解决这个问题就各种方式开始了,
1、MainActivity.java 启动按钮布置

      /**
         * 从Service启动
         */
        findViewById(R.id.bt_servcie).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent wIntent = new Intent(MainActivity.this, WindowService.class);
                startService(wIntent);
            }
        });

        /**
         * 从Activity启动
         */
        findViewById(R.id.bt_activity).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                WindowMnagerUtil.getWindowInstance(MainActivity.this).createWindow(); //会消失
//                WindowMnagerUtil.getWindowInstance(getApplicationContext()).createWindow(); //不会消失
            }
        });

        /**
         * 不使用单例模式启动
         */
        findViewById(R.id.bt_noapplication).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                WindowMnagerNoinstanceUtil.createWindow(MainActivity.this); //会消失
//                WindowMnagerNoinstanceUtil.createWindow(getApplicationContext()); 不会消失
            }
        });

2、第一种方式是先启动WindowService,然后在Service通过WindowManager管 理,我觉得这样做的话和Service特性有关

public class WindowService extends Service {
    public WindowService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
//        WindowMnagerUtil.getWindowInstance(getApplicationContext()).createWindow(); //这个是在Service中用单例模式工具类
        WindowMnagerNoinstanceUtil.createWindow(this);  //在Service中正常启动

        return super.onStartCommand(intent, flags, startId);
    }
}

没想到这种方式是可行的

一开始,Service中是用使用了单例模式工具类,然后我就想,
我在Activity中启动试试,没想到也是可以的,其实主要的原因和是否单利是没有关系的
从实验例子中看到关系是传进去的Context的对象是 actiivty还是Application

至此在这两种特殊的手机机型的解决方法也就明朗了
一种是Service启动WindowMnager
另一种是传application对象

3、WindowManager管理方法

 /**
     * 创建悬浮窗,添加一张美女图
     */
    public void createWindow() {
        final WindowManager windowMnager = getWindowMnager(context);  //得到WindowManager对象
        wmParams = new WindowManager.LayoutParams();
        wmParams.type = WindowManager.LayoutParams.TYPE_TOAST;
        wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
        //只有打电话才会显示在屏幕上方
        wmParams.gravity = Gravity.CENTER;
        wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

        imageView = new ImageView(context);    //设置添加的图片
        imageView.setImageResource(R.mipmap.girl);
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                removeWindow();
            }
        });
        windowMnager.addView(imageView, wmParams);
    }

4、用代码写布局、最外层用FrameLayout
FrameLayout is designed to block out an area on the screen to display a single item. Generally, FrameLayout should be used to hold a single child view, because it can be difficult to organize child views in a way that’s scalable to different screen sizes without the children overlapping each other. You can, however, add multiple children to a FrameLayout and control their position within the FrameLayout by assigning gravity to each child, using the android:layout_gravity attribute.

   //设置最外层FrameLayout布局
        final FrameLayout fl = new FrameLayout(context);
        FrameLayout.LayoutParams flParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        fl.setLayoutParams(flParams);
        fl.setBackgroundColor(Color.BLACK);


        //设置 RelativeLayout布局
        RelativeLayout rl = new RelativeLayout(context);

        FrameLayout.LayoutParams rlp = new FrameLayout.LayoutParams(500, 500);
        rlp.gravity = Gravity.CENTER;       //这两行设置剧中显示 , 使用FrameLayout  属性中 android:layout_gravity  设置居中

        rl.setBackgroundColor(Color.BLUE);
        rl.setLayoutParams(rlp);
        //设置图片
        ImageView imageView = new ImageView(context);    //设置添加的图片
        RelativeLayout.LayoutParams ivParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        rl.addView(imageView, ivParams);
        imageView.setImageResource(R.mipmap.girl);

        fl.addView(rl, rlp);

Reference : http://blog.csdn.net/guolin_blog/article/details/8689140

代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值