1
0
Эх сурвалжийг харах

0.0.49.beta20
- 尝试修复 activity 处于全屏情况下可能存在的输入法弹出对话框无法上移的问题;

0.0.49.beta19
- 尝试修复 #387 #388 bug

0.0.49.beta18
- 尝试修复 #370 bug

0.0.49.beta17
- 修复<=API29的部分设备上存在的非安全区不回调的问题;
- 合并 #377 的 PR
- 其他问题修复

0.0.49.beta14 ready
- 修复 PopNotification 存在的显示位置错误问题;
- 修复 InputDialog 点击背景无法关闭的问题;
- 修复 FullScreenDialog 滑动错位问题;
- 修复 OnBindView 回调 view 不为 customView 的问题;

0.0.49.beta13
- FullScreenDialog 增加 maskColor 设置;
- 修复 IOS 主题下 MessageDialog 使用 build() 构建模式时无法设置背景颜色的问题;
- 修复 CustomDialog 设置 FullScreen 属性无效的问题;

0.0.49.beta12 ready
- 尝试修正 padding属性设置错误的bug(via @Matcha-xiaobin #356);
- 修复了 PopTip 在频繁弹出时某些已经显示的 PopTip 可能存在的导致异常显示在屏幕顶部的问题;
- BottomDialog 增加 setScrollableWhenContentLargeThanVisibleRange(boolean) 允许将自定义布局添加到对话框本身存在的 ScrollView 外,请注意此方法将会使自定义布局添加到 Title Text、Content(Message Text)之间;

0.0.49.beta11
- 修复部分已知问题;

0.0.49.beta10
- 完善 OnBindView 内部逻辑,当dialog和view相同时不重复执行onBind事件;
- WaitDialog新增onShow(DialogXRunnable)和onDismiss(DialogXRunnable);
- 尝试修复可能存在的问题;

0.0.49.beta9
- 菜单布局结构优化;

0.0.49.beta8
- 对话框内的 dialogView 引用进行了处理,以及 PopTip 的 baseView,减少在低版本安卓系统上出现内存泄漏的可能性
- FullScreenDialog 新增了方法 hideActivityContentView(boolean) 用于设置是否在显示 FullScreenDialog 时不对 activity 的界面内容进行渲染,这将提升一定的性能,此方法只可以在使用 build 方法构建且在执行show方法之前使用,但这将引发一些问题,例如输入法弹出时 FullScreenDialog 无法上浮等;
- 其他问题修复;

0.0.49.beta6
- 对 BottomMenu 的 setOkButton、setCancelButton、setOtherButton 提供了单独的 OnBottomMenuButtonClickListener 参数接口,可直接提供 BottomMenu 参数的 onClick 回调事件;
- BottomDialog/BottomMenu 新增 set/get OkTextInfo 和 OtherTextInfo 方法;
- 修复 DialogXBaseRelativeLayout 可能存在的嵌套循环调用 requestFocus() 方法的问题;
- 修复关于 WaitDialog 设置背景颜色不生效的问题;

0.0.49.beta5 ready
- ActivityScreenShotImageView 增加静态方法 useHardwareRenderingMode,开启可使用硬件加速渲染模式;
- 修复部分系统下 ActivityScreenShotImageView 在执行回收时触发的“Software rendering doesn't support hardware bitmaps.”异常;
- 其他问题修复;

0.0.49.beta4 ready
- 修复部分系统下 BlurRelativeLayout 或 BlurRelativeLayout 在执行回收时触发的“Calling RS with no Context active.”异常;
- ActivityScreenShotImageView 截图方案更新;

0.0.49.beta4 ready
- 修复在部分设备上由 DialogXBaseRelativeLayout 引发的 StackOverflowError,此问题猜测跟特定版本系统固件存在问题有关;

0.0.49.beta3
- 修复 ActivityScreenShotImageView 可能引发的“Software rendering doesn’t support hardware bitmaps” 异常;
- 修复 BottomDialog/FullScreenDialog 的滑动事件在内部存在 ScrollController 时,若触摸位置处于 ScrollController 布局外无法滑动对话框的问题;

0.0.49.beta2
- InputInfo新增方法:`getInputFilters()`、`setInputFilters(InputFilter[] inputFilters)`、`addInputFilter(InputFilter inputFilter)` 和 `removeInputFilter(InputFilter inputFilter)`(issues:332);
- 尝试性修复 DialogFragment 模式实现下的 WaitDialog 内存泄漏问题(issues:334);
- 修复关于DialogFragmentImpl引发的空指针问题此问题(issues:335);

0.0.49.beta1
- 修复 BlurRelativeLayout 和 BlurLinearLayout 在 iOS 主题下使用 DialogFragment 模式时存在的渲染宽度和高度 <=0 导致的异常(issues:324);
- 修复 IOS 主题下可能存在的 `RSInvalidStateException: Calling RS with no Context active` 异常问题(issues:327);
- 修复可能存在的高频启关对话框过程中,因UI未完成构建被关闭引发的空指针异常(issues:331);

Kongzue 1 жил өмнө
parent
commit
182b0b5b65

+ 176 - 28
DialogX/src/main/java/com/kongzue/dialogx/util/views/FitSystemBarUtils.java

@@ -3,11 +3,18 @@ package com.kongzue.dialogx.util.views;
 
 import static androidx.core.view.WindowInsetsAnimationCompat.Callback.DISPATCH_MODE_CONTINUE_ON_SUBTREE;
 
+import android.app.Activity;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Rect;
 import android.os.Build;
 import android.util.Log;
+import android.view.Surface;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
 import android.view.WindowInsets;
+import android.view.WindowManager;
 
 import androidx.annotation.NonNull;
 import androidx.core.graphics.Insets;
@@ -17,6 +24,7 @@ import androidx.core.view.WindowInsetsAnimationCompat;
 import androidx.core.view.WindowInsetsCompat;
 
 import com.kongzue.dialogx.DialogX;
+import com.kongzue.dialogx.interfaces.BaseDialog;
 
 import java.util.List;
 
@@ -177,16 +185,16 @@ public class FitSystemBarUtils {
         }
 
         if (ViewCompat.isAttachedToWindow(contentView)) {
-            log("KONGZUE DEBUG DIALOGX: AttachedToWindow ok");
+            log("KONGZUE DEBUG DIALOGX FitSystemBarUtils: AttachedToWindow ok");
             ViewCompat.requestApplyInsets(contentView);
         } else {
-            log("KONGZUE DEBUG DIALOGX: wait AttachedToWindow");
+            log("KONGZUE DEBUG DIALOGX FitSystemBarUtils: wait AttachedToWindow");
             contentView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
                 @Override
                 public void onViewAttachedToWindow(View view) {
                     view.removeOnAttachStateChangeListener(this);
 
-                    log("KONGZUE DEBUG DIALOGX: onViewAttachedToWindow");
+                    log("KONGZUE DEBUG DIALOGX FitSystemBarUtils: onViewAttachedToWindow");
                     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH && Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
                         if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                             //修复<=API29的部分设备上存在的非安全区不回调的问题
@@ -199,10 +207,10 @@ public class FitSystemBarUtils {
                                 public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                                     WindowInsets windowInsets = v.getRootView().getRootWindowInsets();
                                     if (windowInsets != null) {
-                                        log("    KONGZUE DEBUG DIALOGX: RootView get Insets");
+                                        log("    KONGZUE DEBUG DIALOGX FitSystemBarUtils: RootView get Insets");
                                         formatInsets(WindowInsetsCompat.toWindowInsetsCompat(windowInsets), new RelativePadding(initialPadding));
                                     } else {
-                                        log("    KONGZUE DEBUG DIALOGX: RootView not get Insets");
+                                        log("    KONGZUE DEBUG DIALOGX FitSystemBarUtils: RootView not get Insets");
                                     }
                                 }
                             };
@@ -231,10 +239,13 @@ public class FitSystemBarUtils {
         }
     }
 
+    RelativePadding relativePaddingCache;
+
     /**
      * 针对不同版本处理Insets
      */
     private void formatInsets(WindowInsetsCompat insetsCompat, RelativePadding initialPadding) {
+        relativePaddingCache = initialPadding;
         int cutoutPaddingLeft = 0;
         int cutoutPaddingTop = 0;
         int cutoutPaddingRight = 0;
@@ -279,31 +290,60 @@ public class FitSystemBarUtils {
             systemWindowInsetTop = systemBars.top;
         }
         if (isWrongInsets(systemBars)) {
-            return;
-        }
+            log("    KONGZUE DEBUG DIALOGX FitSystemBarUtils: isWrongInsets try special mode...");
+            switch (checkOrientationAndStatusBarSide()) {
+                case 0:
+                    initialPadding.start = getStatusBarHeight();
+                    initialPadding.end = getNavigationBarHeight();
+                    break;
+                case 1:
+                    initialPadding.end = getStatusBarHeight();
+                    initialPadding.start = getNavigationBarHeight();
+                    break;
+                default:
+                    initialPadding.top = getStatusBarHeight();
+                    initialPadding.bottom = getNavigationBarHeight();
+                    break;
+            }
+            addListenerWhenImeHeightChanged();
+        } else {
+            if (callBack.isEnable(Orientation.Top)) {
+                initialPadding.top += Math.max(systemWindowInsetTop, cutoutPaddingTop);
+            }
+            if (callBack.isEnable(Orientation.Bottom)) {
+                initialPadding.bottom += Math.max(systemWindowInsetBottom, cutoutPaddingBottom);
+            }
 
-        if (callBack.isEnable(Orientation.Top)) {
-            initialPadding.top += Math.max(systemWindowInsetTop, cutoutPaddingTop);
-        }
-        if (callBack.isEnable(Orientation.Bottom)) {
-            initialPadding.bottom += Math.max(systemWindowInsetBottom, cutoutPaddingBottom);
+            boolean isRtl =
+                    ViewCompat.getLayoutDirection(contentView) == ViewCompat.LAYOUT_DIRECTION_RTL;
+            if (callBack.isEnable(Orientation.Start)) {
+                if (isRtl) {
+                    initialPadding.start += Math.max(systemWindowInsetRight, cutoutPaddingRight);
+                } else {
+                    initialPadding.start += Math.max(systemWindowInsetLeft, cutoutPaddingLeft);
+                }
+            }
+            if (callBack.isEnable(Orientation.End)) {
+                if (isRtl) {
+                    initialPadding.end += Math.max(systemWindowInsetLeft, cutoutPaddingLeft);
+                } else {
+                    initialPadding.end += Math.max(systemWindowInsetRight, cutoutPaddingRight);
+                }
+            }
         }
 
-        boolean isRtl =
-                ViewCompat.getLayoutDirection(contentView) == ViewCompat.LAYOUT_DIRECTION_RTL;
-        if (callBack.isEnable(Orientation.Start)) {
-            if (isRtl) {
-                initialPadding.start += Math.max(systemWindowInsetRight, cutoutPaddingRight);
-            } else {
-                initialPadding.start += Math.max(systemWindowInsetLeft, cutoutPaddingLeft);
-            }
+        applyCallBack(initialPadding);
+    }
+
+    private void applyCallBack() {
+        if (relativePaddingCache != null) {
+            applyCallBack(relativePaddingCache);
         }
-        if (callBack.isEnable(Orientation.End)) {
-            if (isRtl) {
-                initialPadding.end += Math.max(systemWindowInsetLeft, cutoutPaddingLeft);
-            } else {
-                initialPadding.end += Math.max(systemWindowInsetRight, cutoutPaddingRight);
-            }
+    }
+
+    private void applyCallBack(RelativePadding initialPadding) {
+        if (callBack == null) {
+            return;
         }
         //加上用户自定义的
         initialPadding.start += callBack.initialPadding(Orientation.Start);
@@ -313,13 +353,13 @@ public class FitSystemBarUtils {
 
         initialPadding.applyToView(contentView);
         //四边 非安全区 传递回去
+        log("    KONGZUE DEBUG DIALOGX FitSystemBarUtils callBack: left=" + initialPadding.start + " top=" + initialPadding.top + " right=" + initialPadding.end + " bottom=" + initialPadding.bottom);
         callBack.unsafeRect(
                 initialPadding.start,
                 initialPadding.top,
                 initialPadding.end,
-                initialPadding.bottom
+                initialPadding.bottom + (specialMode ? specialModeImeHeight : 0)
         );
-
     }
 
     private boolean isWrongInsets(Insets systemBars) {
@@ -379,4 +419,112 @@ public class FitSystemBarUtils {
             Log.e(">>>", s);
         }
     }
+
+    private int getStatusBarHeight() {
+        if (isFullScreen()) {
+            return 0;
+        }
+        Resources res;
+        if (contentView == null || contentView.getContext() == null) {
+            res = Resources.getSystem();
+        } else {
+            res = contentView.getContext().getResources();
+        }
+        int result = 0;
+        int resourceId = res.getIdentifier("status_bar_height", "dimen", "android");
+        if (resourceId > 0) {
+            result = res.getDimensionPixelSize(resourceId);
+        }
+        return result;
+    }
+
+    private int getNavigationBarHeight() {
+        if (isFullScreen()) {
+            return 0;
+        }
+        Resources res;
+        if (contentView == null || contentView.getContext() == null) {
+            res = Resources.getSystem();
+        } else {
+            res = contentView.getContext().getResources();
+        }
+        int result = 0;
+        int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
+        if (resourceId > 0) {
+            result = res.getDimensionPixelSize(resourceId);
+        }
+        return result;
+    }
+
+    private boolean isFullScreen() {
+        Activity activity = BaseDialog.getTopActivity();
+        if (activity == null) {
+            return false;
+        }
+        // 通过检查窗口标志来判断
+        int flags = activity.getWindow().getAttributes().flags;
+        if ((flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0) {
+            return true;
+        }
+        // 通过检查系统 UI 标志来判断
+        int uiOptions = activity.getWindow().getDecorView().getSystemUiVisibility();
+        if ((uiOptions & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0) {
+            return true;
+        }
+        return false;
+    }
+
+    private int checkOrientationAndStatusBarSide() {
+        Activity activity = BaseDialog.getTopActivity();
+        if (activity == null) {
+            return 0;
+        }
+        // 判断是否为横屏
+        if (activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
+            // 判断状态栏位置
+            int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
+            switch (rotation) {
+                case Surface.ROTATION_90:
+                    // 设备旋转了 90 度,状态栏在左侧
+                    return -1;
+                case Surface.ROTATION_270:
+                    // 设备旋转了 270 度,状态栏在右侧
+                    return 1;
+                default:
+                    // 其他情况,不应当发生在横屏状态
+                    return 0;
+            }
+        }
+        return 0;
+    }
+
+    private int specialModeImeHeight;
+    private boolean specialMode;
+    private ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener;
+
+    private void addListenerWhenImeHeightChanged() {
+        specialMode = true;
+        Activity activity = BaseDialog.getTopActivity();
+        if (activity == null) {
+            return;
+        }
+        View decorView = activity.getWindow().getDecorView();
+        if (onGlobalLayoutListener != null) {
+            decorView.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
+        }
+        decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
+            @Override
+            public void onGlobalLayout() {
+                Rect r = new Rect();
+                decorView.getWindowVisibleDisplayFrame(r);
+                int screenHeight = decorView.getHeight();
+                int keypadHeight = screenHeight - r.bottom;
+                if (keypadHeight != specialModeImeHeight) {
+                    specialModeImeHeight = keypadHeight;
+                    log("    KONGZUE DEBUG DIALOGX FitSystemBarUtils: specialModeImeHeight=" + specialModeImeHeight);
+                    applyCallBack();
+                }
+            }
+        });
+    }
 }

+ 1 - 1
gradle.properties

@@ -19,7 +19,7 @@ android.useAndroidX=true
 # Automatically convert third-party libraries to use AndroidX
 android.enableJetifier=true
 
-BUILD_VERSION=0.0.49.beta19
+BUILD_VERSION=0.0.49.beta20
 BUILD_VERSION_INT=48
 DIALOGX_STYLE_VERSION=5
 android.nonTransitiveRClass=true