修改Toast层级

2019-06-25  本文已影响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;

总结

遇到层级问题多看看源码

上一篇下一篇

猜你喜欢

热点阅读