Browse Source

Continue to build modules BottomDialog & BottomMenu

kongzue 4 years ago
parent
commit
27dc799d4e
36 changed files with 857 additions and 253 deletions
  1. 39 0
      .idea/misc.xml
  2. 2 0
      DialogX/build.gradle
  3. BIN
      DialogX/libs/DialogXInterface.jar
  4. 88 12
      DialogX/src/main/java/com/kongzue/dialogx/dialogs/BottomDialog.java
  5. 211 48
      DialogX/src/main/java/com/kongzue/dialogx/dialogs/BottomMenu.java
  6. 1 1
      DialogX/src/main/java/com/kongzue/dialogx/dialogs/InputDialog.java
  7. 7 13
      DialogX/src/main/java/com/kongzue/dialogx/dialogs/MessageDialog.java
  8. 1 0
      DialogX/src/main/java/com/kongzue/dialogx/dialogs/WaitDialog.java
  9. 28 0
      DialogX/src/main/java/com/kongzue/dialogx/interfaces/OnIconChangeCallBack.java
  10. 31 0
      DialogX/src/main/java/com/kongzue/dialogx/style/MaterialStyle.java
  11. 78 86
      DialogX/src/main/java/com/kongzue/dialogx/util/BottomDialogTouchEventInterceptor.java
  12. 24 8
      DialogX/src/main/java/com/kongzue/dialogx/util/NormalMenuArrayAdapter.java
  13. 43 7
      DialogX/src/main/java/com/kongzue/dialogx/util/views/DialogXBaseRelativeLayout.java
  14. 7 24
      DialogX/src/main/java/com/kongzue/dialogx/util/views/MaxRelativeLayout.java
  15. 11 0
      DialogX/src/main/res/drawable/rect_dialogx_material_bottom_bkg_night.xml
  16. 6 0
      DialogX/src/main/res/drawable/rect_dialogx_material_dialogtap_night.xml
  17. 11 0
      DialogX/src/main/res/drawable/rect_dialogx_material_menu_split_divider_night.xml
  18. 9 9
      DialogX/src/main/res/layout/layout_dialogx_bottom_material.xml
  19. 88 0
      DialogX/src/main/res/layout/layout_dialogx_bottom_material_dark.xml
  20. 1 1
      DialogXIOSStyle/build.gradle
  21. BIN
      DialogXIOSStyle/libs/DialogXInterface.jar
  22. 5 0
      DialogXIOSStyle/src/main/java/com/kongzue/dialogx/style/IOSStyle.java
  23. 15 0
      DialogXInterface/src/main/java/com/kongzue/dialogx/interfaces/DialogXStyle.java
  24. 1 1
      DialogXKongzueStyle/build.gradle
  25. BIN
      DialogXKongzueStyle/libs/DialogXInterface.jar
  26. 5 0
      DialogXKongzueStyle/src/main/java/com/kongzue/dialogx/style/KongzueStyle.java
  27. 1 1
      DialogXMIUIStyle/build.gradle
  28. BIN
      DialogXMIUIStyle/libs/DialogXInterface.jar
  29. 5 0
      DialogXMIUIStyle/src/main/java/com/kongzue/dialogx/style/MIUIStyle.java
  30. 1 1
      README.md
  31. 1 1
      app/build.gradle
  32. 69 40
      app/src/main/java/com/kongzue/dialogxdemo/MainActivity.java
  33. 1 0
      app/src/main/res/layout/layout_custom_reply.xml
  34. 60 0
      app/src/main/res/layout/layout_custom_reply_dark.xml
  35. BIN
      app/src/main/res/mipmap-xxhdpi/img_dialogx_demo_view.png
  36. 7 0
      app/src/main/res/values/styles.xml

+ 39 - 0
.idea/misc.xml

@@ -84,6 +84,45 @@
       <textMaps />
     </LinkMapSettings>
   </component>
+  <component name="NullableNotNullManager">
+    <option name="myDefaultNullable" value="org.jetbrains.annotations.Nullable" />
+    <option name="myDefaultNotNull" value="android.annotation.NonNull" />
+    <option name="myNullables">
+      <value>
+        <list size="12">
+          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
+          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
+          <item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
+          <item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
+          <item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
+          <item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
+          <item index="6" class="java.lang.String" itemvalue="android.annotation.Nullable" />
+          <item index="7" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
+          <item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.Nullable" />
+          <item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableDecl" />
+          <item index="10" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
+          <item index="11" class="java.lang.String" itemvalue="com.android.annotations.Nullable" />
+        </list>
+      </value>
+    </option>
+    <option name="myNotNulls">
+      <value>
+        <list size="11">
+          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
+          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
+          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
+          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
+          <item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
+          <item index="5" class="java.lang.String" itemvalue="android.annotation.NonNull" />
+          <item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
+          <item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.NonNull" />
+          <item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullDecl" />
+          <item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
+          <item index="10" class="java.lang.String" itemvalue="com.android.annotations.NonNull" />
+        </list>
+      </value>
+    </option>
+  </component>
   <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8 (2)" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/build/classes" />
   </component>

+ 2 - 0
DialogX/build.gradle

@@ -27,4 +27,6 @@ dependencies {
     implementation fileTree(dir: "libs", include: ["*.jar"])
     implementation 'androidx.appcompat:appcompat:1.2.0+'
     api files('libs\\DialogXInterface.jar')
+    implementation files('libs\\DialogXInterface.jar')
+    implementation files('libs\\DialogXInterface.jar')
 }

BIN
DialogX/libs/DialogXInterface.jar


+ 88 - 12
DialogX/src/main/java/com/kongzue/dialogx/dialogs/BottomDialog.java

@@ -2,10 +2,13 @@ package com.kongzue.dialogx.dialogs;
 
 import android.animation.Animator;
 import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
+import android.view.WindowManager;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
 import android.widget.ImageView;
@@ -40,13 +43,14 @@ public class BottomDialog extends BaseDialog {
     protected CharSequence title;
     protected CharSequence message;
     protected CharSequence cancelText;
+    protected boolean allowInterceptTouch = true;
     
-    private DialogLifecycleCallback<BottomDialog> dialogLifecycleCallback;
+    protected DialogLifecycleCallback<BottomDialog> dialogLifecycleCallback;
     
-    protected BottomDialog me;
+    protected BottomDialog me = this;
     
     protected BottomDialog() {
-        me = this;
+        super();
     }
     
     private View dialogView;
@@ -60,23 +64,50 @@ public class BottomDialog extends BaseDialog {
         this.message = message;
     }
     
+    public static BottomDialog show(CharSequence title, CharSequence message) {
+        BottomDialog bottomDialog = new BottomDialog(title, message);
+        bottomDialog.show();
+        return bottomDialog;
+    }
+    
     public BottomDialog(CharSequence title, CharSequence message, OnBindView<BottomDialog> onBindView) {
         this.title = title;
         this.message = message;
         this.onBindView = onBindView;
     }
     
+    public static BottomDialog show(CharSequence title, CharSequence message, OnBindView<BottomDialog> onBindView) {
+        BottomDialog bottomDialog = new BottomDialog(title, message, onBindView);
+        bottomDialog.show();
+        return bottomDialog;
+    }
+    
     public BottomDialog(CharSequence title, OnBindView<BottomDialog> onBindView) {
         this.title = title;
         this.onBindView = onBindView;
     }
     
+    public static BottomDialog show(CharSequence title, OnBindView<BottomDialog> onBindView) {
+        BottomDialog bottomDialog = new BottomDialog(title, onBindView);
+        bottomDialog.show();
+        return bottomDialog;
+    }
+    
     public BottomDialog(OnBindView<BottomDialog> onBindView) {
         this.onBindView = onBindView;
     }
     
+    public static BottomDialog show(OnBindView<BottomDialog> onBindView) {
+        BottomDialog bottomDialog = new BottomDialog(onBindView);
+        bottomDialog.show();
+        return bottomDialog;
+    }
+    
     public void show() {
-        int layoutId = R.layout.layout_dialogx_bottom_material;
+        int layoutId = isLightTheme() ? R.layout.layout_dialogx_bottom_material : R.layout.layout_dialogx_bottom_material_dark;
+        if (style.overrideBottomDialogRes() != null) {
+            layoutId = style.overrideBottomDialogRes().overrideDialogLayout(isLightTheme());
+        }
         
         dialogView = createView(layoutId);
         dialogImpl = new DialogImpl(dialogView);
@@ -87,6 +118,8 @@ public class BottomDialog extends BaseDialog {
     
     public class DialogImpl implements DialogConvertViewInterface {
         
+        private BottomDialogTouchEventInterceptor bottomDialogTouchEventInterceptor;
+        
         public DialogXBaseRelativeLayout boxRoot;
         public RelativeLayout boxBkg;
         public MaxRelativeLayout bkg;
@@ -130,15 +163,13 @@ public class BottomDialog extends BaseDialog {
                     isShow = true;
                     boxRoot.setAlpha(0f);
                     
-                    new BottomDialogTouchEventInterceptor(dialogImpl);
-                    
                     boxContent.getViewTreeObserver().addOnGlobalLayoutListener(onContentViewLayoutChangeListener);
                     
                     getDialogLifecycleCallback().onShow(me);
                     
                     onDialogInit(dialogImpl);
-    
-                    if (onBindView!=null)onBindView.onBind(me, onBindView.getCustomView());
+                    
+                    if (onBindView != null) onBindView.onBind(me, onBindView.getCustomView());
                 }
                 
                 @Override
@@ -161,6 +192,24 @@ public class BottomDialog extends BaseDialog {
                     return false;
                 }
             });
+            
+            bottomDialogTouchEventInterceptor = new BottomDialogTouchEventInterceptor(me, dialogImpl);
+            
+            scrollView.post(new Runnable() {
+                @Override
+                public void run() {
+                    bkg.setY(boxBkg.getHeight());
+                    if (bkg.isChildScrollViewCanScroll()) {
+                        bkgEnterAimY = boxBkg.getHeight() - bkg.getHeight() * 0.6f;
+                    } else {
+                        bkgEnterAimY = boxBkg.getHeight() - bkg.getHeight();
+                    }
+                    ObjectAnimator enterAnim = ObjectAnimator.ofFloat(bkg, "y", boxBkg.getHeight(), bkgEnterAimY);
+                    enterAnim.setDuration(300);
+                    enterAnim.start();
+                    boxRoot.animate().setDuration(enterAnim.getDuration()).alpha(1f).setInterpolator(new DecelerateInterpolator()).setDuration(300).setListener(null);
+                }
+            });
         }
         
         private ViewTreeObserver.OnGlobalLayoutListener onContentViewLayoutChangeListener = new ViewTreeObserver.OnGlobalLayoutListener() {
@@ -210,6 +259,14 @@ public class BottomDialog extends BaseDialog {
                     boxCustom.addView(onBindView.getCustomView(), lp);
                 }
             }
+            
+            if (isAllowInterceptTouch()) {
+                if (imgTab != null) imgTab.setVisibility(View.VISIBLE);
+            } else {
+                if (imgTab != null) imgTab.setVisibility(View.GONE);
+            }
+            
+            bottomDialogTouchEventInterceptor.refresh(me, this);
         }
         
         @Override
@@ -265,6 +322,16 @@ public class BottomDialog extends BaseDialog {
         return this;
     }
     
+    public OnBackPressedListener getOnBackPressedListener() {
+        return onBackPressedListener;
+    }
+    
+    public BottomDialog setOnBackPressedListener(OnBackPressedListener onBackPressedListener) {
+        this.onBackPressedListener = onBackPressedListener;
+        refreshUI();
+        return this;
+    }
+    
     public BottomDialog setStyle(DialogXStyle style) {
         this.style = style;
         return this;
@@ -336,13 +403,22 @@ public class BottomDialog extends BaseDialog {
         return this;
     }
     
-    public OnBackPressedListener getOnBackPressedListener() {
-        return onBackPressedListener;
+    public boolean isAllowInterceptTouch() {
+        if (style.overrideBottomDialogRes() == null) {
+            return false;
+        } else {
+            return allowInterceptTouch && style.overrideBottomDialogRes().touchSlide();
+        }
     }
     
-    public BottomDialog setOnBackPressedListener(OnBackPressedListener onBackPressedListener) {
-        this.onBackPressedListener = onBackPressedListener;
+    public BottomDialog setAllowInterceptTouch(boolean allowInterceptTouch) {
+        this.allowInterceptTouch = allowInterceptTouch;
         refreshUI();
         return this;
     }
+    
+    public BottomDialog setDialogImpl(DialogImpl dialogImpl) {
+        this.dialogImpl = dialogImpl;
+        return this;
+    }
 }

+ 211 - 48
DialogX/src/main/java/com/kongzue/dialogx/dialogs/BottomMenu.java

@@ -1,18 +1,23 @@
 package com.kongzue.dialogx.dialogs;
 
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.AdapterView;
 import android.widget.BaseAdapter;
 import android.widget.RelativeLayout;
-import android.widget.Toast;
 
+import com.kongzue.dialogx.DialogX;
 import com.kongzue.dialogx.R;
+import com.kongzue.dialogx.interfaces.DialogLifecycleCallback;
+import com.kongzue.dialogx.interfaces.DialogXStyle;
 import com.kongzue.dialogx.interfaces.OnBackPressedListener;
+import com.kongzue.dialogx.interfaces.OnBindView;
+import com.kongzue.dialogx.interfaces.OnIconChangeCallBack;
 import com.kongzue.dialogx.util.NormalMenuArrayAdapter;
 import com.kongzue.dialogx.util.views.BottomDialogListView;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import static android.view.View.OVER_SCROLL_NEVER;
@@ -26,69 +31,131 @@ import static android.view.View.OVER_SCROLL_NEVER;
  */
 public class BottomMenu extends BottomDialog {
     
-    protected BottomMenu() {
-        me = this;
-    }
+    protected BottomMenu me = this;
+    
+    /**
+     * 此值用于,当禁用滑动时(style.overrideBottomDialogRes.touchSlide = false时)的最大显示高度。
+     * 0:不限制,最大显示到屏幕可用高度。
+     */
+    protected float bottomDialogMaxHeight = 0.6f;
     
     public static BottomMenu build() {
         return new BottomMenu();
     }
     
+    protected BottomMenu() {
+        super();
+        if (bottomDialogMaxHeight <= 1 && bottomDialogMaxHeight > 0f) {
+            bottomDialogMaxHeight = (int) (getRootFrameLayout().getMeasuredHeight() * bottomDialogMaxHeight);
+        }
+    }
+    
     private OnIconChangeCallBack onIconChangeCallBack;
     private BottomDialogListView listView;
     private BaseAdapter menuArrayAdapter;
     private List<CharSequence> menuList;
     
+    public static BottomMenu show(List<CharSequence> menuList) {
+        BottomMenu bottomMenu = new BottomMenu();
+        bottomMenu.setMenuList(menuList);
+        bottomMenu.show();
+        return bottomMenu;
+    }
+    
+    public static BottomMenu showStringList(List<String> menuList) {
+        BottomMenu bottomMenu = new BottomMenu();
+        bottomMenu.setMenuStringList(menuList);
+        bottomMenu.show();
+        return bottomMenu;
+    }
+    
+    public static BottomMenu show(String[] menuList) {
+        BottomMenu bottomMenu = new BottomMenu();
+        bottomMenu.setMenuList(menuList);
+        bottomMenu.show();
+        return bottomMenu;
+    }
+    
+    public static BottomMenu show(CharSequence[] menuList) {
+        BottomMenu bottomMenu = new BottomMenu();
+        bottomMenu.setMenuList(menuList);
+        bottomMenu.show();
+        return bottomMenu;
+    }
+    
     @Override
     protected void onDialogInit(final DialogImpl dialog) {
         if (dialog != null) {
+            
+            if (!isAllowInterceptTouch()) {
+                dialog.bkg.setMaxHeight((int) bottomDialogMaxHeight);
+                if (bottomDialogMaxHeight != 0) {
+                    dialogImpl.scrollView.setEnabled(false);
+                }
+            }
+            
+            int dividerDrawableResId = isLightTheme() ? R.drawable.rect_dialogx_material_menu_split_divider : R.drawable.rect_dialogx_material_menu_split_divider_night;
+            int dividerHeight = 1;
+            if (style.overrideBottomDialogRes() != null) {
+                dividerDrawableResId = style.overrideBottomDialogRes().overrideMenuDividerDrawableRes(isLightTheme());
+                dividerHeight = style.overrideBottomDialogRes().overrideMenuDividerHeight(isLightTheme());
+            }
+            
             listView = new BottomDialogListView(getContext());
             listView.setOverScrollMode(OVER_SCROLL_NEVER);
-            listView.setDivider(getResources().getDrawable(R.drawable.rect_dialogx_material_menu_split_divider));
-            listView.setDividerHeight(1);
+            listView.setDivider(getResources().getDrawable(dividerDrawableResId));
+            listView.setDividerHeight(dividerHeight);
+            
             RelativeLayout.LayoutParams listViewLp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
             dialog.boxCustom.addView(listView, listViewLp);
-            test();
+            
+            refreshUI();
         }
     }
     
-    private void test() {
-        menuList = new ArrayList<>();
-        menuList.add("添加");
-        menuList.add("查看");
-        menuList.add("编辑");
-        menuList.add("删除");
-        menuList.add("分享");
-        menuList.add("评论");
-        menuList.add("下载");
-        menuList.add("收藏");
-        menuList.add("赞!");
-        menuList.add("不喜欢");
-        menuList.add("所属专辑");
-        menuList.add("复制链接");
-        menuList.add("类似推荐");
-        menuList.add("添加");
-        menuList.add("查看");
-        menuList.add("编辑");
-        menuList.add("删除");
-        menuList.add("分享");
-        menuList.add("评论");
-        menuList.add("下载");
-        menuList.add("收藏");
-        menuList.add("赞!");
-        menuList.add("不喜欢");
-        menuList.add("所属专辑");
-        menuList.add("复制链接");
-        menuList.add("类似推荐");
-        
-        menuArrayAdapter = new NormalMenuArrayAdapter(getContext(), R.layout.item_dialogx_material_bottom_menu_normal_text, menuList, getOnIconChangeCallBack());
-        listView.setAdapter(menuArrayAdapter);
-        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
-            @Override
-            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                Toast.makeText(getContext(), menuList.get(position), Toast.LENGTH_SHORT).show();
+    @Override
+    public void refreshUI() {
+        super.refreshUI();
+        if (listView != null) {
+            if (menuArrayAdapter == null) {
+                menuArrayAdapter = new NormalMenuArrayAdapter(me, getContext(), R.layout.item_dialogx_material_bottom_menu_normal_text, menuList);
+            }
+            if (listView.getAdapter() == null) {
+                listView.setAdapter(menuArrayAdapter);
+            } else {
+                menuArrayAdapter.notifyDataSetChanged();
             }
-        });
+        }
+    }
+    
+    public List<CharSequence> getMenuList() {
+        return menuList;
+    }
+    
+    public BottomMenu setMenuList(List<CharSequence> menuList) {
+        this.menuList = menuList;
+        refreshUI();
+        return this;
+    }
+    
+    public BottomMenu setMenuStringList(List<String> menuList) {
+        this.menuList = new ArrayList<>();
+        this.menuList.addAll(menuList);
+        refreshUI();
+        return this;
+    }
+    
+    public BottomMenu setMenuList(String[] menuList) {
+        this.menuList = new ArrayList<>();
+        this.menuList.addAll(Arrays.asList(menuList));
+        refreshUI();
+        return this;
+    }
+    
+    public BottomMenu setMenuList(CharSequence[] menuList) {
+        this.menuList = Arrays.asList(menuList);
+        refreshUI();
+        return this;
     }
     
     public OnIconChangeCallBack getOnIconChangeCallBack() {
@@ -100,10 +167,6 @@ public class BottomMenu extends BottomDialog {
         return this;
     }
     
-    public interface OnIconChangeCallBack {
-        int getIcon(int index, String menuText);
-    }
-    
     public OnBackPressedListener getOnBackPressedListener() {
         return onBackPressedListener;
     }
@@ -113,4 +176,104 @@ public class BottomMenu extends BottomDialog {
         refreshUI();
         return this;
     }
+    
+    public BottomMenu setDialogLifecycleCallback(DialogLifecycleCallback<BottomDialog> dialogLifecycleCallback) {
+        this.dialogLifecycleCallback = dialogLifecycleCallback;
+        return this;
+    }
+    
+    public BottomMenu setStyle(DialogXStyle style) {
+        this.style = style;
+        return this;
+    }
+    
+    public BottomMenu setTheme(DialogX.THEME theme) {
+        this.theme = theme;
+        return this;
+    }
+    
+    public boolean isCancelable() {
+        return cancelable;
+    }
+    
+    public BottomMenu setCancelable(boolean cancelable) {
+        this.cancelable = cancelable;
+        refreshUI();
+        return this;
+    }
+    
+    public DialogImpl getDialogImpl() {
+        return dialogImpl;
+    }
+    
+    public CharSequence getTitle() {
+        return title;
+    }
+    
+    public BottomMenu setTitle(CharSequence title) {
+        this.title = title;
+        refreshUI();
+        return this;
+    }
+    
+    public CharSequence getMessage() {
+        return message;
+    }
+    
+    public BottomMenu setMessage(CharSequence message) {
+        this.message = message;
+        refreshUI();
+        return this;
+    }
+    
+    public CharSequence getCancelText() {
+        return cancelText;
+    }
+    
+    public BottomMenu setCancelText(CharSequence cancelText) {
+        this.cancelText = cancelText;
+        refreshUI();
+        return this;
+    }
+    
+    public BottomMenu setCustomView(OnBindView<BottomDialog> onBindView) {
+        this.onBindView = onBindView;
+        refreshUI();
+        return this;
+    }
+    
+    public View getCustomView() {
+        if (onBindView == null) return null;
+        return onBindView.getCustomView();
+    }
+    
+    public BottomMenu removeCustomView() {
+        this.onBindView.clean();
+        refreshUI();
+        return this;
+    }
+    
+    public boolean isAllowInterceptTouch() {
+        return super.isAllowInterceptTouch();
+    }
+    
+    public BottomMenu setAllowInterceptTouch(boolean allowInterceptTouch) {
+        this.allowInterceptTouch = allowInterceptTouch;
+        refreshUI();
+        return this;
+    }
+    
+    public BottomMenu setDialogImpl(DialogImpl dialogImpl) {
+        this.dialogImpl = dialogImpl;
+        return this;
+    }
+    
+    public float getBottomDialogMaxHeight() {
+        return bottomDialogMaxHeight;
+    }
+    
+    public BottomMenu setBottomDialogMaxHeight(float bottomDialogMaxHeight) {
+        this.bottomDialogMaxHeight = bottomDialogMaxHeight;
+        return this;
+    }
 }

+ 1 - 1
DialogX/src/main/java/com/kongzue/dialogx/dialogs/InputDialog.java

@@ -19,7 +19,7 @@ import com.kongzue.dialogx.util.TextInfo;
 public class InputDialog extends MessageDialog {
     
     protected InputDialog() {
-        me = this;
+        super();
     }
     
     public static InputDialog build() {

+ 7 - 13
DialogX/src/main/java/com/kongzue/dialogx/dialogs/MessageDialog.java

@@ -44,12 +44,12 @@ import com.kongzue.dialogx.util.TextInfo;
 public class MessageDialog extends BaseDialog {
     
     protected OnBindView<MessageDialog> onBindView;
-    protected MessageDialog me;
+    protected MessageDialog me = this;
     
     private DialogLifecycleCallback<MessageDialog> dialogLifecycleCallback;
     
     protected MessageDialog() {
-        me = this;
+        super();
     }
     
     private View dialogView;
@@ -121,15 +121,9 @@ public class MessageDialog extends BaseDialog {
     protected DialogImpl dialogImpl;
     
     public void show() {
-        int layoutId = R.layout.layout_dialogx_material;
-        switch (theme) {
-            case LIGHT:
-                layoutId = style.layout(true);
-                break;
-            case DARK:
-                layoutId = style.layout(false);
-                break;
-        }
+        int layoutId = style.layout(isLightTheme());
+        layoutId = layoutId == 0 ? (isLightTheme() ? R.layout.layout_dialogx_material : R.layout.layout_dialogx_material_dark) : layoutId;
+        
         dialogView = createView(layoutId);
         dialogImpl = new DialogImpl(dialogView);
         show(dialogView);
@@ -219,8 +213,8 @@ public class MessageDialog extends BaseDialog {
                             }
                         }, 300);
                     }
-    
-                    if (onBindView!=null)onBindView.onBind(me, onBindView.getCustomView());
+                    
+                    if (onBindView != null) onBindView.onBind(me, onBindView.getCustomView());
                 }
                 
                 @Override

+ 1 - 0
DialogX/src/main/java/com/kongzue/dialogx/dialogs/WaitDialog.java

@@ -51,6 +51,7 @@ public class WaitDialog extends BaseDialog {
     private DialogLifecycleCallback<WaitDialog> dialogLifecycleCallback;
     
     protected WaitDialog() {
+        super();
         me = new WeakReference<>(this);
         cancelable = false;
     }

+ 28 - 0
DialogX/src/main/java/com/kongzue/dialogx/interfaces/OnIconChangeCallBack.java

@@ -0,0 +1,28 @@
+package com.kongzue.dialogx.interfaces;
+
+import com.kongzue.dialogx.dialogs.BottomMenu;
+
+/**
+ * @author: Kongzue
+ * @github: https://github.com/kongzue/
+ * @homepage: http://kongzue.com/
+ * @mail: myzcxhh@live.cn
+ * @createTime: 2020/10/9 14:54
+ */
+public abstract class OnIconChangeCallBack {
+    
+    private boolean autoTintIconInLightOrDarkMode;
+    
+    public OnIconChangeCallBack() {
+    }
+    
+    public OnIconChangeCallBack(boolean autoTintIconInLightOrDarkMode) {
+        this.autoTintIconInLightOrDarkMode = autoTintIconInLightOrDarkMode;
+    }
+    
+    public abstract int getIcon(BottomMenu bottomMenu, int index, String menuText);
+    
+    public boolean isAutoTintIconInLightOrDarkMode() {
+        return autoTintIconInLightOrDarkMode;
+    }
+}

+ 31 - 0
DialogX/src/main/java/com/kongzue/dialogx/style/MaterialStyle.java

@@ -118,4 +118,35 @@ public class MaterialStyle implements DialogXStyle {
             }
         };
     }
+    
+    @Override
+    public BottomDialogRes overrideBottomDialogRes() {
+        return new BottomDialogRes() {
+            @Override
+            public boolean touchSlide() {
+                return true;
+            }
+            
+            @Override
+            public int overrideDialogLayout(boolean light) {
+                return light ? R.layout.layout_dialogx_bottom_material : R.layout.layout_dialogx_bottom_material_dark;
+            }
+            
+            @Override
+            public int overrideMenuDividerDrawableRes(boolean light) {
+                return light ? R.drawable.rect_dialogx_material_menu_split_divider : R.drawable.rect_dialogx_material_menu_split_divider_night;
+            }
+            
+            @Override
+            public int overrideMenuDividerHeight(boolean light) {
+                return 1;
+            }
+    
+            @Override
+            public int overrideMenuTextColor(boolean light) {
+                return light?R.color.black90:R.color.white90;
+            }
+    
+        };
+    }
 }

+ 78 - 86
DialogX/src/main/java/com/kongzue/dialogx/util/BottomDialogTouchEventInterceptor.java

@@ -38,8 +38,14 @@ public class BottomDialogTouchEventInterceptor {
      */
     private int oldMode;
     
-    public BottomDialogTouchEventInterceptor(final BottomDialog.DialogImpl impl) {
-        
+    public BottomDialogTouchEventInterceptor(BottomDialog me, BottomDialog.DialogImpl impl) {
+        refresh(me, impl);
+    }
+    
+    public void refresh(final BottomDialog me, final BottomDialog.DialogImpl impl) {
+        if (me == null || impl == null || impl.bkg == null || impl.scrollView == null) {
+            return;
+        }
         /**
          * BottomDialog 触控事件说明:
          * bkg 将拦截并接管所有触控操作。
@@ -53,100 +59,86 @@ public class BottomDialogTouchEventInterceptor {
          *     super.onMeasure(widthMeasureSpec, expandSpec);
          * }
          */
-        impl.bkg.setTouchCallBack(new View.OnTouchListener() {
-            @Override
-            public boolean onTouch(View v, MotionEvent event) {
-                switch (event.getAction()) {
-                    case MotionEvent.ACTION_DOWN:
-                        bkgTouchDownY = event.getY();
-                        isBkgTouched = true;
-                        bkgOldY = impl.bkg.getY();
-                        break;
-                    case MotionEvent.ACTION_MOVE:
-                        if (isBkgTouched) {
-                            float aimY = impl.bkg.getY() + event.getY() - bkgTouchDownY;
-                            if (aimY < 0 || impl.scrollView.getScrollY() != 0) {
-                                if (impl.bkg.isChildScrollViewCanScroll()) {
-                                    if (oldMode == 0) {
+        if (me.isAllowInterceptTouch()) {
+            impl.bkg.setTouchCallBack(new View.OnTouchListener() {
+                @Override
+                public boolean onTouch(View v, MotionEvent event) {
+                    switch (event.getAction()) {
+                        case MotionEvent.ACTION_DOWN:
+                            bkgTouchDownY = event.getY();
+                            isBkgTouched = true;
+                            bkgOldY = impl.bkg.getY();
+                            break;
+                        case MotionEvent.ACTION_MOVE:
+                            if (isBkgTouched) {
+                                float aimY = impl.bkg.getY() + event.getY() - bkgTouchDownY;
+                                if (aimY < 0 || impl.scrollView.getScrollY() != 0) {
+                                    if (impl.bkg.isChildScrollViewCanScroll()) {
+                                        if (oldMode == 0) {
+                                            bkgTouchDownY = event.getY();
+                                            scrolledY = 0;
+                                        }
+                                        
+                                        impl.scrollView.scrollTo(0, (int) (scrolledY - (event.getY() - bkgTouchDownY)));
+                                        impl.bkg.setY(0);
+                                        
+                                        oldMode = -1;
+                                    }
+                                } else {
+                                    if (oldMode == -1) {
                                         bkgTouchDownY = event.getY();
-                                        scrolledY = 0;
+                                        aimY = impl.bkg.getY() + event.getY() - bkgTouchDownY;
                                     }
                                     
-                                    impl.scrollView.scrollTo(0, (int) (scrolledY - (event.getY() - bkgTouchDownY)));
-                                    impl.bkg.setY(0);
-                                    
-                                    oldMode = -1;
-                                }
-                            } else {
-                                if (oldMode == -1) {
-                                    bkgTouchDownY = event.getY();
-                                    aimY = impl.bkg.getY() + event.getY() - bkgTouchDownY;
-                                }
-                                
-                                if (impl.bkg.isChildScrollViewCanScroll()) {
-                                    impl.bkg.setY(aimY);
-                                } else {
-                                    if (aimY > impl.bkgEnterAimY) {
+                                    if (impl.bkg.isChildScrollViewCanScroll()) {
                                         impl.bkg.setY(aimY);
+                                    } else {
+                                        if (aimY > impl.bkgEnterAimY) {
+                                            impl.bkg.setY(aimY);
+                                        }
                                     }
+                                    
+                                    oldMode = 0;
                                 }
-                                
-                                oldMode = 0;
-                            }
-                        }
-                        break;
-                    case MotionEvent.ACTION_UP:
-                    case MotionEvent.ACTION_CANCEL:
-                        scrolledY = impl.scrollView.getScrollY();
-                        isBkgTouched = false;
-                        if (bkgOldY == 0) {
-                            if (impl.bkg.getY() < dip2px(35)){
-                                ObjectAnimator enterAnim = ObjectAnimator.ofFloat(impl.bkg, "y", impl.bkg.getY(), 0);
-                                enterAnim.setDuration(300);
-                                enterAnim.start();
-                            }else if (impl.bkg.getY() > impl.bkgEnterAimY + dip2px(35)) {
-                                impl.preDismiss();
-                            } else {
-                                ObjectAnimator enterAnim = ObjectAnimator.ofFloat(impl.bkg, "y", impl.bkg.getY(), impl.bkgEnterAimY);
-                                enterAnim.setDuration(300);
-                                enterAnim.start();
                             }
-                        } else {
-                            if (impl.bkg.getY() < bkgOldY - dip2px(35)) {
-                                ObjectAnimator enterAnim = ObjectAnimator.ofFloat(impl.bkg, "y", impl.bkg.getY(), 0);
-                                enterAnim.setDuration(300);
-                                enterAnim.start();
-                            } else if (impl.bkg.getY() > bkgOldY + dip2px(35)) {
-                                impl.preDismiss();
+                            break;
+                        case MotionEvent.ACTION_UP:
+                        case MotionEvent.ACTION_CANCEL:
+                            scrolledY = impl.scrollView.getScrollY();
+                            isBkgTouched = false;
+                            if (bkgOldY == 0) {
+                                if (impl.bkg.getY() < dip2px(35)) {
+                                    ObjectAnimator enterAnim = ObjectAnimator.ofFloat(impl.bkg, "y", impl.bkg.getY(), 0);
+                                    enterAnim.setDuration(300);
+                                    enterAnim.start();
+                                } else if (impl.bkg.getY() > impl.bkgEnterAimY + dip2px(35)) {
+                                    impl.preDismiss();
+                                } else {
+                                    ObjectAnimator enterAnim = ObjectAnimator.ofFloat(impl.bkg, "y", impl.bkg.getY(), impl.bkgEnterAimY);
+                                    enterAnim.setDuration(300);
+                                    enterAnim.start();
+                                }
                             } else {
-                                ObjectAnimator enterAnim = ObjectAnimator.ofFloat(impl.bkg, "y", impl.bkg.getY(), impl.bkgEnterAimY);
-                                enterAnim.setDuration(300);
-                                enterAnim.start();
+                                if (impl.bkg.getY() < bkgOldY - dip2px(35)) {
+                                    ObjectAnimator enterAnim = ObjectAnimator.ofFloat(impl.bkg, "y", impl.bkg.getY(), 0);
+                                    enterAnim.setDuration(300);
+                                    enterAnim.start();
+                                } else if (impl.bkg.getY() > bkgOldY + dip2px(35)) {
+                                    impl.preDismiss();
+                                } else {
+                                    ObjectAnimator enterAnim = ObjectAnimator.ofFloat(impl.bkg, "y", impl.bkg.getY(), impl.bkgEnterAimY);
+                                    enterAnim.setDuration(300);
+                                    enterAnim.start();
+                                }
                             }
-                        }
-                        break;
-                }
-                return true;
-            }
-        });
-        
-        impl.scrollView.post(new Runnable() {
-            @Override
-            public void run() {
-                impl.bkg.setY(impl.boxBkg.getHeight());
-                if (impl.bkg.isChildScrollViewCanScroll()) {
-                    impl.bkgEnterAimY = impl.boxBkg.getHeight() - impl.bkg.getHeight() * 0.6f;
-                } else {
-                    impl.bkgEnterAimY = impl.boxBkg.getHeight() - impl.bkg.getHeight();
+                            break;
+                    }
+                    return true;
                 }
-                ObjectAnimator enterAnim = ObjectAnimator.ofFloat(impl.bkg, "y", impl.boxBkg.getHeight(), impl.bkgEnterAimY);
-                enterAnim.setDuration(300);
-                enterAnim.start();
-                impl.boxRoot.animate().setDuration(enterAnim.getDuration()).alpha(1f).setInterpolator(new DecelerateInterpolator()).setDuration(300).setListener(null);
-                
-                impl.bkg.setInterceptTouchEvent(true);
-            }
-        });
+            });
+        } else {
+            impl.bkg.setTouchCallBack(null);
+        }
     }
     
     private int dip2px(float dpValue) {

+ 24 - 8
DialogX/src/main/java/com/kongzue/dialogx/util/NormalMenuArrayAdapter.java

@@ -1,7 +1,7 @@
 package com.kongzue.dialogx.util;
 
 import android.content.Context;
-import android.graphics.Color;
+import android.content.res.ColorStateList;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -21,22 +21,22 @@ import java.util.List;
  * @mail: myzcxhh@live.cn
  * @createTime: 2020/10/7 0:00
  */
-public class NormalMenuArrayAdapter extends ArrayAdapter {
+public class NormalMenuArrayAdapter extends ArrayAdapter<CharSequence> {
     
-    private BottomMenu.OnIconChangeCallBack onIconChangeCallBack;
+    private BottomMenu bottomMenu;
     public int resoureId;
     public List<CharSequence> objects;
     public Context context;
     
-    public NormalMenuArrayAdapter(Context context, int resourceId, List<CharSequence> objects, BottomMenu.OnIconChangeCallBack onIconChangeCallBack) {
+    public NormalMenuArrayAdapter(BottomMenu bottomMenu, Context context, int resourceId, List<CharSequence> objects) {
         super(context, resourceId, objects);
         this.objects = objects;
         this.resoureId = resourceId;
         this.context = context;
-        this.onIconChangeCallBack = onIconChangeCallBack;
+        this.bottomMenu = bottomMenu;
     }
     
-    public class ViewHolder {
+    class ViewHolder {
         ImageView imgDialogxMenuIcon;
         TextView txtDialogxMenuText;
     }
@@ -72,13 +72,29 @@ public class NormalMenuArrayAdapter extends ArrayAdapter {
             viewHolder = (ViewHolder) convertView.getTag();
         }
         CharSequence text = objects.get(position);
+        
+        int textColor = bottomMenu.isLightTheme() ? R.color.black90 : R.color.white90;
+        if (bottomMenu.getStyle().overrideBottomDialogRes() != null) {
+            if (bottomMenu.getStyle().overrideBottomDialogRes().overrideMenuTextColor(bottomMenu.isLightTheme()) != 0) {
+                textColor = bottomMenu.getStyle().overrideBottomDialogRes().overrideMenuTextColor(bottomMenu.isLightTheme());
+            }
+        }
+        
         if (null != text) {
             viewHolder.txtDialogxMenuText.setText(text);
-            if (onIconChangeCallBack != null) {
-                int resId = onIconChangeCallBack.getIcon(position, text.toString());
+            viewHolder.txtDialogxMenuText.setTextColor(context.getResources().getColor(textColor));
+            
+            if (bottomMenu.getOnIconChangeCallBack() != null) {
+                int resId = bottomMenu.getOnIconChangeCallBack().getIcon(bottomMenu, position, text.toString());
+                boolean autoTintIconInLightOrDarkMode = bottomMenu.getOnIconChangeCallBack().isAutoTintIconInLightOrDarkMode();
+                
                 if (resId != 0) {
                     viewHolder.imgDialogxMenuIcon.setVisibility(View.VISIBLE);
                     viewHolder.imgDialogxMenuIcon.setImageResource(resId);
+                    
+                    if (autoTintIconInLightOrDarkMode) {
+                        viewHolder.imgDialogxMenuIcon.setImageTintList(ColorStateList.valueOf(context.getResources().getColor(textColor)));
+                    }
                 } else {
                     viewHolder.imgDialogxMenuIcon.setVisibility(View.GONE);
                 }

+ 43 - 7
DialogX/src/main/java/com/kongzue/dialogx/util/views/DialogXBaseRelativeLayout.java

@@ -1,5 +1,7 @@
 package com.kongzue.dialogx.util.views;
 
+import android.annotation.TargetApi;
+import android.app.Activity;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Rect;
@@ -10,6 +12,7 @@ import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewParent;
+import android.view.ViewTreeObserver;
 import android.view.WindowInsets;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.RelativeLayout;
@@ -17,6 +20,7 @@ import android.widget.RelativeLayout;
 import androidx.core.view.ViewCompat;
 
 import com.kongzue.dialogx.R;
+import com.kongzue.dialogx.interfaces.BaseDialog;
 import com.kongzue.dialogx.interfaces.OnBackPressedListener;
 
 import java.util.Arrays;
@@ -54,9 +58,19 @@ public class DialogXBaseRelativeLayout extends RelativeLayout {
         init();
     }
     
+    private boolean isInited = false;
+    
     private void init() {
-        setFocusableInTouchMode(true);
-        requestFocus();
+        if (!isInited) {
+            setFocusableInTouchMode(true);
+            requestFocus();
+        }
+    }
+    
+    @Override
+    protected boolean fitSystemWindows(Rect insets) {
+        paddingView(insets.left, insets.top, insets.right, insets.bottom);
+        return super.fitSystemWindows(insets);
     }
     
     @Override
@@ -67,6 +81,13 @@ public class DialogXBaseRelativeLayout extends RelativeLayout {
         return super.dispatchApplyWindowInsets(insets);
     }
     
+    public void paddingView(WindowInsets insets) {
+        if (insets == null) return;
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            paddingView(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
+        }
+    }
+    
     @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
         if (event.getAction() == KeyEvent.ACTION_UP && event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
@@ -89,21 +110,37 @@ public class DialogXBaseRelativeLayout extends RelativeLayout {
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         final ViewParent parent = getParent();
-    
+        
         ViewCompat.setFitsSystemWindows(this, ViewCompat.getFitsSystemWindows((View) parent));
         ViewCompat.requestApplyInsets(this);
         
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !isInEditMode()) {
+            ((Activity) BaseDialog.getContext()).getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(decorViewLayoutListener);
+        }
+        
         if (onLifecycleCallBack != null) {
             onLifecycleCallBack.onShow();
         }
     }
     
+    private ViewTreeObserver.OnGlobalLayoutListener decorViewLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
+        @Override
+        public void onGlobalLayout() {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+                paddingView(getRootWindowInsets());
+            }
+        }
+    };
+    
     @Override
     protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
+        if (decorViewLayoutListener != null) {
+            ((Activity) BaseDialog.getContext()).getWindow().getDecorView().getViewTreeObserver().removeOnGlobalLayoutListener(decorViewLayoutListener);
+        }
         if (onLifecycleCallBack != null) {
             onLifecycleCallBack.onDismiss();
         }
+        super.onDetachedFromWindow();
     }
     
     @Override
@@ -117,8 +154,7 @@ public class DialogXBaseRelativeLayout extends RelativeLayout {
     }
     
     public abstract static class OnLifecycleCallBack {
-        public void onShow() {
-        }
+        public void onShow() { }
         
         public abstract void onDismiss();
     }
@@ -127,7 +163,7 @@ public class DialogXBaseRelativeLayout extends RelativeLayout {
         MaxRelativeLayout bkgView = findViewById(R.id.bkg);
         if (bkgView != null) {
             LayoutParams bkgLp = (LayoutParams) bkgView.getLayoutParams();
-            if(bkgLp.getRules()[ALIGN_PARENT_BOTTOM] == RelativeLayout.TRUE){
+            if (bkgLp.getRules()[ALIGN_PARENT_BOTTOM] == RelativeLayout.TRUE) {
                 bkgView.setPadding(0, 0, 0, bottom);
                 setPadding(left, top, right, 0);
                 return;

+ 7 - 24
DialogX/src/main/java/com/kongzue/dialogx/util/views/MaxRelativeLayout.java

@@ -2,22 +2,12 @@ package com.kongzue.dialogx.util.views;
 
 import android.content.Context;
 import android.content.res.TypedArray;
-import android.graphics.Canvas;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewParent;
 import android.widget.RelativeLayout;
 import android.widget.ScrollView;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.core.view.NestedScrollingChildHelper;
-import androidx.core.view.NestedScrollingParent;
-import androidx.core.view.NestedScrollingParent2;
-import androidx.core.view.NestedScrollingParentHelper;
-import androidx.core.view.ViewCompat;
 
 import com.kongzue.dialogx.R;
 
@@ -102,20 +92,10 @@ public class MaxRelativeLayout extends RelativeLayout {
     
     private boolean isMove = false;
     private int touchY, touchX;
-    private boolean interceptTouchEvent;
-    
-    public boolean isInterceptTouchEvent() {
-        return interceptTouchEvent;
-    }
-    
-    public MaxRelativeLayout setInterceptTouchEvent(boolean interceptTouchEvent) {
-        this.interceptTouchEvent = interceptTouchEvent;
-        return this;
-    }
     
     @Override
     public boolean onInterceptTouchEvent(MotionEvent event) {
-        if (onTouchListener != null && interceptTouchEvent) {
+        if (onTouchListener != null) {
             onTouchListener.onTouch(this, event);
             switch (event.getAction()) {
                 case MotionEvent.ACTION_DOWN:
@@ -134,10 +114,10 @@ public class MaxRelativeLayout extends RelativeLayout {
                         touchX = (int) event.getRawX();
                     }
                     isMove = true;
-                
+                    
                     float moveY = event.getRawY();
                     float moveX = event.getRawX();
-                
+                    
                     if (Math.abs(moveY - touchY) > dip2px(20) || Math.abs(moveX - touchX) > dip2px(20)) {
                         final ViewParent parent = getParent();
                         if (parent != null) {
@@ -149,11 +129,14 @@ public class MaxRelativeLayout extends RelativeLayout {
             }
             return isMove;
         }
-        return false;
+        return super.onInterceptTouchEvent(event);
     }
     
     public boolean isChildScrollViewCanScroll() {
         if (childScrollView == null) return false;
+        if (!childScrollView.isEnabled()){
+            return false;
+        }
         View child = childScrollView.getChildAt(0);
         if (child != null) {
             int childHeight = child.getHeight();

+ 11 - 0
DialogX/src/main/res/drawable/rect_dialogx_material_bottom_bkg_night.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!--left to right-->
+    <solid
+        android:color="@color/dialogxMaterialDarkDialogBkgColor"/>
+
+    <corners
+        android:topRightRadius="10dp"
+        android:topLeftRadius="10dp"/>
+</shape>

+ 6 - 0
DialogX/src/main/res/drawable/rect_dialogx_material_dialogtap_night.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="@color/white10"/>
+    <corners android:radius="99dp" />
+</shape>

+ 11 - 0
DialogX/src/main/res/drawable/rect_dialogx_material_menu_split_divider_night.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item
+        android:left="55dp">
+        <shape android:shape="rectangle" >
+            <solid android:color="@color/white10" />
+        </shape>
+    </item>
+
+</layer-list>

+ 9 - 9
DialogX/src/main/res/layout/layout_dialogx_bottom_material.xml

@@ -19,20 +19,20 @@
             android:background="@drawable/rect_dialogx_material_bottom_bkg_light"
             android:focusableInTouchMode="true">
 
-            <ImageView
-                android:id="@+id/img_tab"
-                android:layout_width="30dp"
-                android:layout_height="4dp"
-                android:layout_centerHorizontal="true"
-                android:layout_marginTop="10dp"
-                android:src="@drawable/rect_dialogx_material_dialogtap" />
-
             <LinearLayout
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="15dp"
+                android:paddingTop="10dp"
                 android:orientation="vertical">
 
+                <ImageView
+                    android:id="@+id/img_tab"
+                    android:layout_width="30dp"
+                    android:layout_height="4dp"
+                    android:layout_gravity="center_horizontal"
+                    android:layout_marginBottom="1dp"
+                    android:src="@drawable/rect_dialogx_material_dialogtap" />
+
                 <TextView
                     android:id="@+id/txt_dialog_title"
                     android:layout_width="match_parent"

+ 88 - 0
DialogX/src/main/res/layout/layout_dialogx_bottom_material_dark.xml

@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/box_root"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/black40"
+    android:orientation="vertical">
+
+    <RelativeLayout
+        android:id="@+id/box_bkg"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <com.kongzue.dialogx.util.views.MaxRelativeLayout
+            android:id="@+id/bkg"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentBottom="true"
+            android:background="@drawable/rect_dialogx_material_bottom_bkg_night"
+            android:focusableInTouchMode="true">
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical">
+
+                <ImageView
+                    android:id="@+id/img_tab"
+                    android:layout_width="30dp"
+                    android:layout_height="4dp"
+                    android:layout_gravity="center_horizontal"
+                    android:layout_marginTop="10dp"
+                    android:layout_marginBottom="1dp"
+                    android:src="@drawable/rect_dialogx_material_dialogtap_night" />
+
+                <TextView
+                    android:id="@+id/txt_dialog_title"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_horizontal"
+                    android:gravity="center_vertical"
+                    android:paddingHorizontal="20dp"
+                    android:paddingBottom="10dp"
+                    android:text="Title"
+                    android:textColor="@color/white"
+                    android:textSize="21dp" />
+
+                <ScrollView
+                    android:id="@+id/scrollView"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:overScrollMode="never"
+                    android:scrollbarSize="7dp"
+                    android:scrollbars="vertical">
+
+                    <LinearLayout
+                        android:id="@+id/box_content"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:orientation="vertical">
+
+                        <TextView
+                            android:id="@+id/txt_dialog_tip"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:layout_marginHorizontal="20dp"
+                            android:paddingBottom="5dp"
+                            android:text="This is content text."
+                            android:textColor="@color/white60"
+                            android:textSize="16dp" />
+
+                        <RelativeLayout
+                            android:id="@+id/box_custom"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"/>
+
+                    </LinearLayout>
+
+                </ScrollView>
+
+            </LinearLayout>
+
+        </com.kongzue.dialogx.util.views.MaxRelativeLayout>
+
+    </RelativeLayout>
+
+</com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout>

+ 1 - 1
DialogXIOSStyle/build.gradle

@@ -20,5 +20,5 @@ android {
 
 dependencies {
     implementation fileTree(dir: "libs", include: ["*.jar"])
-    implementation project(path: ':DialogXInterface')
+    implementation files('libs\\DialogXInterface.jar')
 }

BIN
DialogXIOSStyle/libs/DialogXInterface.jar


+ 5 - 0
DialogXIOSStyle/src/main/java/com/kongzue/dialogx/style/IOSStyle.java

@@ -146,4 +146,9 @@ public class IOSStyle implements DialogXStyle {
             }
         };
     }
+    
+    @Override
+    public BottomDialogRes overrideBottomDialogRes() {
+        return null;
+    }
 }

+ 15 - 0
DialogXInterface/src/main/java/com/kongzue/dialogx/interfaces/DialogXStyle.java

@@ -32,6 +32,8 @@ public interface DialogXStyle {
     
     WaitTipRes overrideWaitTipRes();
     
+    BottomDialogRes overrideBottomDialogRes();
+    
     interface BlurBackgroundSetting {
         
         boolean blurBackground();
@@ -67,4 +69,17 @@ public interface DialogXStyle {
         
         int overrideTextColorRes(boolean light);
     }
+    
+    interface BottomDialogRes {
+        
+        boolean touchSlide();
+        
+        int overrideDialogLayout(boolean light);
+        
+        int overrideMenuDividerDrawableRes(boolean light);
+    
+        int overrideMenuDividerHeight(boolean light);
+    
+        int overrideMenuTextColor(boolean light);
+    }
 }

+ 1 - 1
DialogXKongzueStyle/build.gradle

@@ -20,5 +20,5 @@ android {
 
 dependencies {
     implementation fileTree(dir: "libs", include: ["*.jar"])
-    implementation project(path: ':DialogXInterface')
+    implementation files('libs\\DialogXInterface.jar')
 }

BIN
DialogXKongzueStyle/libs/DialogXInterface.jar


+ 5 - 0
DialogXKongzueStyle/src/main/java/com/kongzue/dialogx/style/KongzueStyle.java

@@ -88,4 +88,9 @@ public class KongzueStyle implements DialogXStyle {
             }
         };
     }
+    
+    @Override
+    public BottomDialogRes overrideBottomDialogRes() {
+        return null;
+    }
 }

+ 1 - 1
DialogXMIUIStyle/build.gradle

@@ -21,5 +21,5 @@ android {
 
 dependencies {
     implementation fileTree(dir: "libs", include: ["*.jar"])
-    implementation project(path: ':DialogXInterface')
+    implementation files('libs\\DialogXInterface.jar')
 }

BIN
DialogXMIUIStyle/libs/DialogXInterface.jar


+ 5 - 0
DialogXMIUIStyle/src/main/java/com/kongzue/dialogx/style/MIUIStyle.java

@@ -88,4 +88,9 @@ public class MIUIStyle implements DialogXStyle {
             }
         };
     }
+    
+    @Override
+    public BottomDialogRes overrideBottomDialogRes() {
+        return null;
+    }
 }

+ 1 - 1
README.md

@@ -7,7 +7,7 @@ DialogX 采用分离设计,默认自带 Material 主题,可选引入 IOS、K
 
 更低的耦合度,无论对话框是否正在显示,请肆意执行的 Activity 关闭逻辑,而无需担心引发 WindowLeaked 错误。
 
-目前开发进度:60% [●●●●●●●●●●●●○○○○○○○○]
+目前开发进度:62% [●●●●●●●●●●●●○○○○○○○○]
 
 ## 开发计划
 

+ 1 - 1
app/build.gradle

@@ -28,7 +28,7 @@ repositories{
 }
 dependencies {
     implementation fileTree(dir: "libs", include: ["*.jar"])
-    implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
+    implementation 'androidx.appcompat:appcompat:1.2.0'
     implementation 'com.kongzue.baseframeworkx:baseframework:6.7.6'
     implementation project(':DialogX')
     implementation project(path: ':DialogXIOSStyle')

+ 69 - 40
app/src/main/java/com/kongzue/dialogxdemo/MainActivity.java

@@ -1,7 +1,9 @@
 package com.kongzue.dialogxdemo;
 
+import android.content.Context;
 import android.graphics.Color;
 import android.view.View;
+import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
@@ -25,15 +27,19 @@ import com.kongzue.dialogx.dialogs.MessageDialog;
 import com.kongzue.dialogx.dialogs.TipDialog;
 import com.kongzue.dialogx.dialogs.WaitDialog;
 import com.kongzue.dialogx.interfaces.BaseDialog;
+import com.kongzue.dialogx.interfaces.DialogLifecycleCallback;
 import com.kongzue.dialogx.interfaces.OnBackPressedListener;
 import com.kongzue.dialogx.interfaces.OnBindView;
 import com.kongzue.dialogx.interfaces.OnDialogButtonClickListener;
+import com.kongzue.dialogx.interfaces.OnIconChangeCallBack;
 import com.kongzue.dialogx.style.IOSStyle;
 import com.kongzue.dialogx.style.KongzueStyle;
 import com.kongzue.dialogx.style.MIUIStyle;
 import com.kongzue.dialogx.style.MaterialStyle;
 import com.kongzue.dialogx.util.TextInfo;
 
+import java.util.ArrayList;
+
 @Layout(R.layout.activity_main)
 @DarkStatusBarTheme(true)
 @DarkNavigationBarTheme(true)
@@ -163,7 +169,13 @@ public class MainActivity extends BaseActivity {
         btnMessageDialog.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View view) {
-                new MessageDialog("标题", "正文内容", "确定").show();
+                MessageDialog.show("标题", "正文内容", "确定").setOkButton(new OnDialogButtonClickListener() {
+                    @Override
+                    public boolean onClick(BaseDialog baseDialog, View v) {
+                        toast("点击确定按钮");
+                        return false;
+                    }
+                });
             }
         });
         
@@ -294,60 +306,67 @@ public class MainActivity extends BaseActivity {
         btnBottomMenu.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                BottomMenu.build().setOnIconChangeCallBack(new BottomMenu.OnIconChangeCallBack() {
-                    @Override
-                    public int getIcon(int index, String menuText) {
-                        switch (menuText) {
-                            case "添加":
-                                return R.mipmap.img_dialogx_demo_add;
-                            case "查看":
-                                return R.mipmap.img_dialogx_demo_view;
-                            case "编辑":
-                                return R.mipmap.img_dialogx_demo_edit;
-                            case "删除":
-                                return R.mipmap.img_dialogx_demo_delete;
-                            case "分享":
-                                return R.mipmap.img_dialogx_demo_share;
-                            case "评论":
-                                return R.mipmap.img_dialogx_demo_comment;
-                            case "下载":
-                                return R.mipmap.img_dialogx_demo_download;
-                            case "收藏":
-                                return R.mipmap.img_dialogx_demo_favorite;
-                            case "赞!":
-                                return R.mipmap.img_dialogx_demo_link;
-                            case "不喜欢":
-                                return R.mipmap.img_dialogx_demo_dislike;
-                            case "所属专辑":
-                                return R.mipmap.img_dialogx_demo_album;
-                            case "复制链接":
-                                return R.mipmap.img_dialogx_demo_link;
-                            case "类似推荐":
-                                return R.mipmap.img_dialogx_demo_recommend;
-                        }
-                        return 0;
-                    }
-                }).show();
+                BottomMenu.show(new String[]{"添加", "查看", "编辑", "删除", "分享", "评论", "下载", "收藏", "赞!", "不喜欢", "所属专辑", "复制链接", "类似推荐", "添加", "查看", "编辑", "删除", "分享", "评论", "下载", "收藏", "赞!", "不喜欢", "所属专辑", "复制链接", "类似推荐"})
+                        .setOnIconChangeCallBack(new OnIconChangeCallBack(true) {
+                            @Override
+                            public int getIcon(BottomMenu bottomMenu, int index, String menuText) {
+                                switch (menuText) {
+                                    case "添加":
+                                        return R.mipmap.img_dialogx_demo_add;
+                                    case "查看":
+                                        return R.mipmap.img_dialogx_demo_view;
+                                    case "编辑":
+                                        return R.mipmap.img_dialogx_demo_edit;
+                                    case "删除":
+                                        return R.mipmap.img_dialogx_demo_delete;
+                                    case "分享":
+                                        return R.mipmap.img_dialogx_demo_share;
+                                    case "评论":
+                                        return R.mipmap.img_dialogx_demo_comment;
+                                    case "下载":
+                                        return R.mipmap.img_dialogx_demo_download;
+                                    case "收藏":
+                                        return R.mipmap.img_dialogx_demo_favorite;
+                                    case "赞!":
+                                        return R.mipmap.img_dialogx_demo_good;
+                                    case "不喜欢":
+                                        return R.mipmap.img_dialogx_demo_dislike;
+                                    case "所属专辑":
+                                        return R.mipmap.img_dialogx_demo_album;
+                                    case "复制链接":
+                                        return R.mipmap.img_dialogx_demo_link;
+                                    case "类似推荐":
+                                        return R.mipmap.img_dialogx_demo_recommend;
+                                }
+                                return 0;
+                            }
+                        });
             }
         });
         
         btnBottomReply.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                BottomDialog.build().setCustomView(new OnBindView<BottomDialog>(R.layout.layout_custom_reply) {
+                BottomDialog.show(new OnBindView<BottomDialog>(rdoDark.isChecked() ? R.layout.layout_custom_reply_dark : R.layout.layout_custom_reply) {
                     @Override
-                    public void onBind(BottomDialog dialog, View v) {
+                    public void onBind(final BottomDialog dialog, View v) {
                         btnReplyCommit = v.findViewById(R.id.btn_reply_commit);
                         editReplyCommit = v.findViewById(R.id.edit_reply_commit);
-    
                         btnReplyCommit.setOnClickListener(new View.OnClickListener() {
                             @Override
                             public void onClick(View v) {
-                                toast("提交内容:\n"+editReplyCommit.getText().toString());
+                                dialog.dismiss();
+                                toast("提交内容:\n" + editReplyCommit.getText().toString());
                             }
                         });
+                        editReplyCommit.postDelayed(new Runnable() {
+                            @Override
+                            public void run() {
+                                showIME(editReplyCommit);
+                            }
+                        }, 300);
                     }
-                }).show();
+                }).setAllowInterceptTouch(false);
             }
         });
     }
@@ -357,4 +376,14 @@ public class MainActivity extends BaseActivity {
         log("#MainActivity.onBackPressed");
         super.onBackPressed();
     }
+    
+    public void showIME(EditText editText) {
+        if (editText == null) {
+            return;
+        }
+        editText.requestFocus();
+        editText.setFocusableInTouchMode(true);
+        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+        imm.showSoftInput(editText, InputMethodManager.RESULT_UNCHANGED_SHOWN);
+    }
 }

+ 1 - 0
app/src/main/res/layout/layout_custom_reply.xml

@@ -41,6 +41,7 @@
         android:hint="请输入内容..."
         android:inputType="textMultiLine"
         android:minHeight="100dp"
+        android:maxHeight="200dp"
         android:paddingHorizontal="15dp"
         android:paddingVertical="5dp"
         android:textSize="16dp" />

+ 60 - 0
app/src/main/res/layout/layout_custom_reply_dark.xml

@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center_vertical"
+        android:orientation="horizontal">
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="35dp"
+            android:layout_weight="1"
+            android:gravity="center_vertical"
+            android:paddingHorizontal="15dp"
+            android:text="回复"
+            android:textColor="@color/white90"
+            android:textSize="16dp" />
+
+        <TextView
+            android:id="@+id/btn_reply_commit"
+            android:layout_width="wrap_content"
+            android:layout_height="35dp"
+            android:gravity="center_vertical"
+            android:paddingHorizontal="15dp"
+            android:text="发布"
+            android:textColor="@color/dialogxColorBlue"
+            android:textSize="16dp" />
+
+    </LinearLayout>
+
+    <EditText
+        android:id="@+id/edit_reply_commit"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="@color/empty"
+        android:gravity="left|top"
+        android:hint="请输入内容..."
+        android:inputType="textMultiLine"
+        android:minHeight="100dp"
+        android:maxHeight="200dp"
+        android:textColor="@color/white"
+        android:textColorHint="@color/white50"
+        android:paddingHorizontal="15dp"
+        android:paddingVertical="5dp"
+        android:textSize="16dp" />
+
+    <CheckBox
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="10dp"
+        android:layout_marginBottom="10dp"
+        android:textColor="@color/white"
+        android:theme="@style/AppThemeDark"
+        android:text="回复并转发" />
+
+</LinearLayout>

BIN
app/src/main/res/mipmap-xxhdpi/img_dialogx_demo_view.png


+ 7 - 0
app/src/main/res/values/styles.xml

@@ -7,4 +7,11 @@
         <item name="colorAccent">@color/colorAccent</item>
     </style>
 
+    <!-- Base application theme. -->
+    <style name="AppThemeDark" parent="Theme.AppCompat.NoActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+        <item name="colorAccent">@color/colorAccent</item>
+    </style>
 </resources>