From 5fc70d8dafe13d528294c08a2f8bf87c1c765493 Mon Sep 17 00:00:00 2001 From: razerdp Date: Wed, 16 Sep 2020 12:15:43 +0800 Subject: [PATCH] =?UTF-8?q?*=20**=E3=80=90Candy=E3=80=912.2.8.0916**=20(20?= =?UTF-8?q?20/09/16)=20=20=20*=20=E9=80=82=E9=85=8DApi30=20[#349](https://?= =?UTF-8?q?github.com/razerdp/BasePopup/issues/349)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 + build.gradle | 8 +- .../razerdp/basepopup/BasePopupHelper.java | 18 +-- .../basepopup/PopupDecorViewProxy.java | 9 +- .../razerdp/basepopup/PopupMaskLayout.java | 18 ++- .../razerdp/basepopup/WindowManagerProxy.java | 132 ++++++++++++------ .../main/java/razerdp/blur/BlurImageView.java | 1 + 7 files changed, 119 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index 7f21a223..af996a5c 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,8 @@ * **【Candy】2.2.8.0909** (2020/09/09) * 添加BasePopupUnsafe,这个工具类是个核弹,请谨慎使用 * 去掉BasePopup接口 +* **【Candy】2.2.8.0916** (2020/09/16) + * 适配Api30 [#349](https://github.com/razerdp/BasePopup/issues/349) diff --git a/build.gradle b/build.gradle index e3fa5309..622e7b9e 100644 --- a/build.gradle +++ b/build.gradle @@ -34,12 +34,12 @@ task clean(type: Delete) { ext { //Android - compileSdkVersion = 29 + compileSdkVersion = 30 minSdkVersion = 19 minLibSdkVersion = 16 - targetSdkVersion = 29 - versionCode = 137 - versionName = '2.2.8.0909' + targetSdkVersion = 30 + versionCode = 138 + versionName = '2.2.8.0916' candy = true group = 'com.github.razerdp' diff --git a/lib/src/main/java/razerdp/basepopup/BasePopupHelper.java b/lib/src/main/java/razerdp/basepopup/BasePopupHelper.java index f3411073..b06d6eea 100644 --- a/lib/src/main/java/razerdp/basepopup/BasePopupHelper.java +++ b/lib/src/main/java/razerdp/basepopup/BasePopupHelper.java @@ -5,7 +5,6 @@ import android.app.Dialog; import android.content.Context; import android.content.res.Resources; -import android.graphics.Point; import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; @@ -30,13 +29,14 @@ import android.widget.FrameLayout; import android.widget.LinearLayout; -import java.util.Map; -import java.util.WeakHashMap; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; import androidx.fragment.app.Fragment; + +import java.util.Map; +import java.util.WeakHashMap; + import razerdp.blur.PopupBlurOption; import razerdp.library.R; import razerdp.util.KeyboardUtils; @@ -138,7 +138,6 @@ enum ShowMode { int mSoftInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; ViewGroup.MarginLayoutParams layoutParams; - Point mTempOffset = new Point(); int maxWidth, maxHeight, minWidth, minHeight; @@ -492,15 +491,6 @@ public Rect getAnchorViewBound() { return mAnchorViewBound; } - Point getTempOffset() { - return mTempOffset; - } - - Point setTempOffset(int x, int y) { - mTempOffset.set(x, y); - return mTempOffset; - } - boolean isBackPressEnable() { return (flag & BACKPRESS_ENABLE) != 0; } diff --git a/lib/src/main/java/razerdp/basepopup/PopupDecorViewProxy.java b/lib/src/main/java/razerdp/basepopup/PopupDecorViewProxy.java index 58b8fc63..41c935e5 100644 --- a/lib/src/main/java/razerdp/basepopup/PopupDecorViewProxy.java +++ b/lib/src/main/java/razerdp/basepopup/PopupDecorViewProxy.java @@ -65,12 +65,8 @@ private void init(BasePopupHelper helper) { mHelper.mKeyboardStateChangeListener = this; setClipChildren(mHelper.isClipChildren()); mMaskLayout = new PopupMaskLayout(getContext(), mHelper); - setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, - LayoutParams.MATCH_PARENT)); - addViewInLayout(mMaskLayout, - -1, - new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, - LayoutParams.MATCH_PARENT)); + setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); + addViewInLayout(mMaskLayout, -1, new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); } public void wrapPopupDecorView(final View target, WindowManager.LayoutParams params) { @@ -336,7 +332,6 @@ private void measureWrappedDecorView(View mTarget, int widthMeasureSpec, int hei @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { getLocationOnScreen(location); - mHelper.setTempOffset(location[0], location[1]); layoutInternal(l, t, r, b); } diff --git a/lib/src/main/java/razerdp/basepopup/PopupMaskLayout.java b/lib/src/main/java/razerdp/basepopup/PopupMaskLayout.java index 85ae157d..0f0ebe93 100644 --- a/lib/src/main/java/razerdp/basepopup/PopupMaskLayout.java +++ b/lib/src/main/java/razerdp/basepopup/PopupMaskLayout.java @@ -20,9 +20,10 @@ */ class PopupMaskLayout extends FrameLayout implements BasePopupEvent.EventObserver, ClearMemoryObject { - private BlurImageView mBlurImageView; + BlurImageView mBlurImageView; private BackgroundViewHolder mBackgroundViewHolder; private BasePopupHelper mPopupHelper; + private int[] location = null; private PopupMaskLayout(Context context) { super(context); @@ -52,6 +53,7 @@ public void onClick(View v) { private void init(Context context, BasePopupHelper mHelper) { this.mPopupHelper = mHelper; + location = null; setLayoutAnimation(null); if (mHelper == null) { setBackgroundColor(Color.TRANSPARENT); @@ -60,9 +62,6 @@ private void init(Context context, BasePopupHelper mHelper) { mHelper.observerEvent(this, this); if (mHelper.isAllowToBlur()) { mBlurImageView = new BlurImageView(context); - mBlurImageView.setCutoutX(mHelper.getTempOffset().x); - mBlurImageView.setCutoutY(mHelper.getTempOffset().y); - mBlurImageView.applyBlurOption(mHelper.getBlurOption()); addViewInLayout(mBlurImageView, -1, generateDefaultLayoutParams()); } if (mHelper.getBackgroundView() != null) { @@ -77,6 +76,17 @@ private void init(Context context, BasePopupHelper mHelper) { } } + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + if (location == null && mPopupHelper != null && mPopupHelper.isAllowToBlur() && mBlurImageView != null) { + location = new int[2]; + getLocationOnScreen(location); + mBlurImageView.setCutoutX(location[0]); + mBlurImageView.setCutoutY(location[1]); + mBlurImageView.applyBlurOption(mPopupHelper.getBlurOption()); + } + super.onLayout(changed, left, top, right, bottom); + } public void handleAlignBackground(int gravity, int contentLeft, int contentTop, int contentRight, int contentBottom) { int left = getLeft(); diff --git a/lib/src/main/java/razerdp/basepopup/WindowManagerProxy.java b/lib/src/main/java/razerdp/basepopup/WindowManagerProxy.java index dc07ecdd..0a326c54 100644 --- a/lib/src/main/java/razerdp/basepopup/WindowManagerProxy.java +++ b/lib/src/main/java/razerdp/basepopup/WindowManagerProxy.java @@ -8,12 +8,14 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; +import android.view.WindowInsets; import android.view.WindowManager; +import androidx.annotation.Nullable; + import java.util.HashMap; import java.util.LinkedList; -import androidx.annotation.Nullable; import razerdp.util.PopupUiUtils; import razerdp.util.log.PopupLog; @@ -28,6 +30,15 @@ final class WindowManagerProxy implements WindowManager, ClearMemoryObject { PopupDecorViewProxy mPopupDecorViewProxy; BasePopupHelper mPopupHelper; boolean isAddedToQueue; + static final WindowFlagCompat FLAG_COMPAT; + + static { + if (Build.VERSION.SDK_INT >= 30) { + FLAG_COMPAT = new WindowFlagCompat.Api30Impl(); + } else { + FLAG_COMPAT = new WindowFlagCompat.BeforeApi30Impl(); + } + } WindowManagerProxy(WindowManager windowManager, BasePopupHelper helper) { mWindowManager = windowManager; @@ -42,8 +53,8 @@ public Display getDefaultDisplay() { @Override public void removeViewImmediate(View view) { PopupLog.i(TAG, - "WindowManager.removeViewImmediate >>> " + (view == null ? null : view.getClass() - .getSimpleName())); + "WindowManager.removeViewImmediate >>> " + (view == null ? null : view.getClass() + .getSimpleName())); PopupWindowQueueManager.getInstance().remove(this); if (mWindowManager == null || view == null) return; if (isPopupInnerDecorView(view) && mPopupDecorViewProxy != null) { @@ -62,7 +73,7 @@ public void removeViewImmediate(View view) { @Override public void addView(View view, ViewGroup.LayoutParams params) { PopupLog.i(TAG, - "WindowManager.addView >>> " + (view == null ? null : view.getClass().getName())); + "WindowManager.addView >>> " + (view == null ? null : view.getClass().getName())); PopupWindowQueueManager.getInstance().put(this); if (mWindowManager == null || view == null) return; if (isPopupInnerDecorView(view)) { @@ -70,7 +81,7 @@ public void addView(View view, ViewGroup.LayoutParams params) { * 此时的params是WindowManager.LayoutParams,需要留意强转问题 * popup内部有scrollChangeListener,会有params强转为WindowManager.LayoutParams的情况 */ - applyHelper(params, mPopupHelper); + FLAG_COMPAT.setupFlag(params, mPopupHelper); //添加popup主体 mPopupDecorViewProxy = new PopupDecorViewProxy(view.getContext(), mPopupHelper); mPopupDecorViewProxy.wrapPopupDecorView(view, (LayoutParams) params); @@ -80,36 +91,6 @@ public void addView(View view, ViewGroup.LayoutParams params) { } } - private void applyHelper(ViewGroup.LayoutParams params, BasePopupHelper helper) { - if (params instanceof LayoutParams && helper != null) { - LayoutParams p = (LayoutParams) params; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - Activity decorAct = mPopupHelper.mPopupWindow.getContext(); - if (decorAct != null) { - WindowManager.LayoutParams lp = decorAct.getWindow().getAttributes(); - p.layoutInDisplayCutoutMode = lp.layoutInDisplayCutoutMode; - } - } - if (helper.isOverlayStatusbar()) { - PopupLog.i(TAG, "applyHelper >>> 覆盖状态栏"); - p.flags |= LayoutParams.FLAG_LAYOUT_IN_SCREEN; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - PopupLog.i(TAG, "applyHelper >>> 覆盖导航栏"); - p.flags |= LayoutParams.FLAG_LAYOUT_IN_OVERSCAN; - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - int cutoutGravity = mPopupHelper.getCutoutGravity(); - if (cutoutGravity == Gravity.TOP || cutoutGravity == Gravity.BOTTOM) { - //垂直方向允许占用刘海 - p.layoutInDisplayCutoutMode = LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; - } - - } - p.flags |= LayoutParams.FLAG_LAYOUT_NO_LIMITS; - } - } - } - private ViewGroup.LayoutParams fitLayoutParamsPosition(ViewGroup.LayoutParams params) { if (params instanceof LayoutParams) { LayoutParams p = (LayoutParams) params; @@ -123,7 +104,7 @@ private ViewGroup.LayoutParams fitLayoutParamsPosition(ViewGroup.LayoutParams pa p.width = ViewGroup.LayoutParams.MATCH_PARENT; p.height = ViewGroup.LayoutParams.MATCH_PARENT; } - applyHelper(p, mPopupHelper); + FLAG_COMPAT.setupFlag(p, mPopupHelper); } return params; } @@ -131,8 +112,8 @@ private ViewGroup.LayoutParams fitLayoutParamsPosition(ViewGroup.LayoutParams pa @Override public void updateViewLayout(View view, ViewGroup.LayoutParams params) { PopupLog.i(TAG, - "WindowManager.updateViewLayout >>> " + (view == null ? null : view.getClass() - .getName())); + "WindowManager.updateViewLayout >>> " + (view == null ? null : view.getClass() + .getName())); if (mWindowManager == null || view == null) return; if (isPopupInnerDecorView(view) && mPopupDecorViewProxy != null || view == mPopupDecorViewProxy) { mWindowManager.updateViewLayout(mPopupDecorViewProxy, fitLayoutParamsPosition(params)); @@ -167,8 +148,8 @@ public void update() { @Override public void removeView(View view) { PopupLog.i(TAG, - "WindowManager.removeView >>> " + (view == null ? null : view.getClass() - .getSimpleName())); + "WindowManager.removeView >>> " + (view == null ? null : view.getClass() + .getSimpleName())); PopupWindowQueueManager.getInstance().remove(this); if (mWindowManager == null || view == null) return; if (isPopupInnerDecorView(view) && mPopupDecorViewProxy != null) { @@ -287,4 +268,75 @@ WindowManagerProxy preWindow(WindowManagerProxy managerProxy) { return null; } } + + + interface WindowFlagCompat { + void setupFlag(ViewGroup.LayoutParams params, BasePopupHelper helper); + + class BeforeApi30Impl implements WindowFlagCompat { + + @Override + public void setupFlag(ViewGroup.LayoutParams params, BasePopupHelper helper) { + if (params instanceof LayoutParams && helper != null) { + LayoutParams p = (LayoutParams) params; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + Activity decorAct = helper.mPopupWindow.getContext(); + if (decorAct != null) { + WindowManager.LayoutParams lp = decorAct.getWindow().getAttributes(); + p.layoutInDisplayCutoutMode = lp.layoutInDisplayCutoutMode; + } + } + if (helper.isOverlayStatusbar()) { + PopupLog.i(TAG, "applyHelper >>> 覆盖状态栏"); + p.flags |= LayoutParams.FLAG_LAYOUT_IN_SCREEN; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + int cutoutGravity = helper.getCutoutGravity(); + if (cutoutGravity == Gravity.TOP || cutoutGravity == Gravity.BOTTOM) { + //垂直方向允许占用刘海 + p.layoutInDisplayCutoutMode = LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; + } + + } + p.flags |= LayoutParams.FLAG_LAYOUT_NO_LIMITS; + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + p.flags |= LayoutParams.FLAG_LAYOUT_IN_OVERSCAN; + } + } + } + } + + class Api30Impl implements WindowFlagCompat { + + @Override + public void setupFlag(ViewGroup.LayoutParams params, BasePopupHelper helper) { + if (params instanceof LayoutParams && helper != null) { + LayoutParams p = (LayoutParams) params; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + Activity decorAct = helper.mPopupWindow.getContext(); + if (decorAct != null) { + WindowManager.LayoutParams lp = decorAct.getWindow().getAttributes(); + p.layoutInDisplayCutoutMode = lp.layoutInDisplayCutoutMode; + } + } + int insetsType = p.getFitInsetsTypes(); + if (helper.isOverlayStatusbar()) { + PopupLog.i(TAG, "applyHelper >>> 覆盖状态栏"); + insetsType &= ~WindowInsets.Type.statusBars(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + int cutoutGravity = helper.getCutoutGravity(); + if (cutoutGravity == Gravity.TOP || cutoutGravity == Gravity.BOTTOM) { + //垂直方向允许占用刘海 + p.layoutInDisplayCutoutMode = LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; + } + } + } + insetsType &= ~WindowInsets.Type.navigationBars(); + p.setFitInsetsTypes(insetsType); + } + + } + } + } } diff --git a/lib/src/main/java/razerdp/blur/BlurImageView.java b/lib/src/main/java/razerdp/blur/BlurImageView.java index b99588f0..2e6bb7a6 100644 --- a/lib/src/main/java/razerdp/blur/BlurImageView.java +++ b/lib/src/main/java/razerdp/blur/BlurImageView.java @@ -315,6 +315,7 @@ class CreateBlurBitmapRunnable implements Runnable { CreateBlurBitmapRunnable(View target) { outWidth = target.getWidth(); outHeight = target.getHeight(); + PopupLog.i("aaadf", cutoutX, cutoutY); mBitmap = BlurHelper.getViewBitmap(target, mBlurOption.getBlurPreScaleRatio(), mBlurOption .isFullScreen(), cutoutX, cutoutY); }