美文网首页
修改Toast层级

修改Toast层级

作者: 小马要加油 | 来源:发表于2019-06-25 15:10 被阅读0次

    问题阐述

    我遇到一个需求,要在通知栏这边点击一个通知,阻止点击进入,所以要弹一个Toast提示下不能进去呢。
    这简单啊
    在BaseStatusBar的NotificationClicker的onClickeded toast一下就好了啊

       protected class NotificationClicker implements View.OnClickListener {
            private PendingIntent mIntent;
            private final String mNotificationKey;
            private boolean mIsHeadsUp;
    
            public NotificationClicker(PendingIntent intent, String notificationKey, boolean forHun) {
                mIntent = intent;
                mNotificationKey = notificationKey;
                mIsHeadsUp = forHun;
            }
    
            public void onClick(final View v) {
                if ("XXX"){
                    Toast toast =  Toast.makeText(mContext,"不能进哦",Toast.LENGTH_LONG);
                    toast.show();
                    return;
                }
            .....
    }
    

    三下五除二,噼里啪啦,运行,弹,,,,弹 不出来。。。
    后来把通知栏滑上去之后发现其实toast有弹,就是层级没有通知栏高,被盖住了而已。

    解决办法

    改层级啊,进入源码看看Toast的层级 Toast.java

     private static class TN extends ITransientNotification.Stub {
      
            TN() {
                // 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.format = PixelFormat.TRANSLUCENT;
                params.windowAnimations = com.android.internal.R.style.Animation_Toast;
                params.type = WindowManager.LayoutParams.TYPE_TOAST;
                params.setTitle("Toast");
                params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                        | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
            }
    

    再看下通知栏的层级PhoneStatusBar.java

      private WindowManager.LayoutParams getNavigationBarLayoutParams() {
            WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                    LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
                    WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
                        0
                        | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
                        | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                    PixelFormat.TRANSLUCENT);
            // this will allow the navbar to run in an overlay on devices that support this
            if (ActivityManager.isHighEndGfx()) {
                lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
            }
    
            lp.setTitle("NavigationBar");
            lp.windowAnimations = 0;
            return lp;
        }
    

    所以说把Toast的层级改成比TYPE_NAVIGATION_BAR高就搞定啦。

    修改

    拿到Toast的LayoutParams ,该就对了。
    怎么拿?别看ide没有提醒,实际上有这个方法,只是被hide了

        /**
         * Gets the LayoutParams for the Toast window.
         * @hide
         */
        public WindowManager.LayoutParams getWindowParams() {
            return mTN.mParams;
        }
    

    那我们就好办啦

                    Toast toast =  Toast.makeText(mContext,"不能点击哦",Toast.LENGTH_LONG);
                    //通知栏层级为TYPE_NAVIGATION_BAR,toast默认为TYPE_TOAST,需要提高toast的层级
                    WindowManager.LayoutParams  layoutParams = toast.getWindowParams();
                    layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
                    toast.show();
                    return;
    

    总结

    遇到层级问题多看看源码

    相关文章

      网友评论

          本文标题:修改Toast层级

          本文链接:https://www.haomeiwen.com/subject/ljzuqctx.html