Browse Source

add bottomMenu test

kongzue 4 years ago
parent
commit
c50347cdcc
24 changed files with 530 additions and 150 deletions
  1. 52 113
      DialogX/src/main/java/com/kongzue/dialogx/dialogs/BottomDialog.java
  2. 97 0
      DialogX/src/main/java/com/kongzue/dialogx/dialogs/BottomMenu.java
  3. 136 0
      DialogX/src/main/java/com/kongzue/dialogx/util/BottomDialogTouchEventInterceptor.java
  4. 92 0
      DialogX/src/main/java/com/kongzue/dialogx/util/NormalMenuArrayAdapter.java
  5. 41 0
      DialogX/src/main/java/com/kongzue/dialogx/util/views/BottomDialogListView.java
  6. 4 13
      DialogX/src/main/java/com/kongzue/dialogx/util/views/MaxRelativeLayout.java
  7. 11 0
      DialogX/src/main/res/drawable/rect_dialogx_material_menu_split_divider.xml
  8. 32 0
      DialogX/src/main/res/layout/item_dialogx_material_bottom_menu_normal_text.xml
  9. 1 1
      DialogX/src/main/res/layout/layout_dialogx_bottom_material.xml
  10. 28 0
      app/src/main/java/com/kongzue/dialogxdemo/MainActivity.java
  11. 36 23
      app/src/main/res/layout/activity_main.xml
  12. BIN
      app/src/main/res/mipmap-xxhdpi/img_dialogx_demo_add.png
  13. BIN
      app/src/main/res/mipmap-xxhdpi/img_dialogx_demo_album.png
  14. BIN
      app/src/main/res/mipmap-xxhdpi/img_dialogx_demo_comment.png
  15. BIN
      app/src/main/res/mipmap-xxhdpi/img_dialogx_demo_delete.png
  16. BIN
      app/src/main/res/mipmap-xxhdpi/img_dialogx_demo_dislike.png
  17. BIN
      app/src/main/res/mipmap-xxhdpi/img_dialogx_demo_download.png
  18. BIN
      app/src/main/res/mipmap-xxhdpi/img_dialogx_demo_edit.png
  19. BIN
      app/src/main/res/mipmap-xxhdpi/img_dialogx_demo_favorite.png
  20. BIN
      app/src/main/res/mipmap-xxhdpi/img_dialogx_demo_good.png
  21. BIN
      app/src/main/res/mipmap-xxhdpi/img_dialogx_demo_link.png
  22. BIN
      app/src/main/res/mipmap-xxhdpi/img_dialogx_demo_recommend.png
  23. BIN
      app/src/main/res/mipmap-xxhdpi/img_dialogx_demo_share.png
  24. BIN
      app/src/main/res/mipmap-xxhdpi/img_dialogx_demo_view.png

+ 52 - 113
DialogX/src/main/java/com/kongzue/dialogx/dialogs/BottomDialog.java

@@ -4,9 +4,11 @@ import android.animation.Animator;
 import android.animation.ObjectAnimator;
 import android.animation.ObjectAnimator;
 import android.view.MotionEvent;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.View;
+import android.view.ViewTreeObserver;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
 import android.widget.ImageView;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.RelativeLayout;
 import android.widget.RelativeLayout;
 import android.widget.ScrollView;
 import android.widget.ScrollView;
 import android.widget.TextView;
 import android.widget.TextView;
@@ -19,6 +21,7 @@ import com.kongzue.dialogx.interfaces.DialogConvertViewInterface;
 import com.kongzue.dialogx.interfaces.DialogLifecycleCallback;
 import com.kongzue.dialogx.interfaces.DialogLifecycleCallback;
 import com.kongzue.dialogx.interfaces.DialogXStyle;
 import com.kongzue.dialogx.interfaces.DialogXStyle;
 import com.kongzue.dialogx.interfaces.OnBackPressedListener;
 import com.kongzue.dialogx.interfaces.OnBackPressedListener;
+import com.kongzue.dialogx.util.BottomDialogTouchEventInterceptor;
 import com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout;
 import com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout;
 import com.kongzue.dialogx.util.views.MaxRelativeLayout;
 import com.kongzue.dialogx.util.views.MaxRelativeLayout;
 
 
@@ -51,36 +54,42 @@ public class BottomDialog extends BaseDialog {
     
     
     protected DialogImpl dialogImpl;
     protected DialogImpl dialogImpl;
     
     
-    class DialogImpl implements DialogConvertViewInterface {
+    public class DialogImpl implements DialogConvertViewInterface {
         
         
-        DialogXBaseRelativeLayout boxRoot;
-        RelativeLayout boxBkg;
-        MaxRelativeLayout bkg;
-        ImageView imgTab;
-        TextView txtDialogTitle;
-        ScrollView scrollView;
-        TextView txtDialogTip;
-        RelativeLayout boxCustom;
+        public DialogXBaseRelativeLayout boxRoot;
+        public RelativeLayout boxBkg;
+        public MaxRelativeLayout bkg;
+        public ImageView imgTab;
+        public TextView txtDialogTitle;
+        public ScrollView scrollView;
+        public LinearLayout boxContent;
+        public TextView txtDialogTip;
+        public RelativeLayout boxCustom;
         
         
         public DialogImpl(View convertView) {
         public DialogImpl(View convertView) {
             boxRoot = convertView.findViewById(R.id.box_root);
             boxRoot = convertView.findViewById(R.id.box_root);
-            bkg = convertView.findViewById(R.id.bkg);
             boxBkg = convertView.findViewById(R.id.box_bkg);
             boxBkg = convertView.findViewById(R.id.box_bkg);
+            bkg = convertView.findViewById(R.id.bkg);
             imgTab = convertView.findViewById(R.id.img_tab);
             imgTab = convertView.findViewById(R.id.img_tab);
             txtDialogTitle = convertView.findViewById(R.id.txt_dialog_title);
             txtDialogTitle = convertView.findViewById(R.id.txt_dialog_title);
             scrollView = convertView.findViewById(R.id.scrollView);
             scrollView = convertView.findViewById(R.id.scrollView);
+            boxContent = convertView.findViewById(R.id.box_content);
             txtDialogTip = convertView.findViewById(R.id.txt_dialog_tip);
             txtDialogTip = convertView.findViewById(R.id.txt_dialog_tip);
             boxCustom = convertView.findViewById(R.id.box_custom);
             boxCustom = convertView.findViewById(R.id.box_custom);
             init();
             init();
             refreshView();
             refreshView();
         }
         }
         
         
-        private boolean isBkgTouched = false;
-        private float bkgTouchDownY;
-        private boolean isSvTouched = false;
-        private boolean isInterceptTouched = false;
-        private float svTouchDownY;
-        private float bkgEnterAimY;
+        /**
+         * 此值记录了BottomDialog启动后的位置
+         * ·当内容高度大于屏幕安全区高度时,BottomDialog会以全屏方式启动,但一开始只会展开到 0.8×屏幕高度,
+         * 此时可以再次上划查看全部内容。
+         * ·当内容高度小于屏幕安全区高度时,BottomDialog会以内容高度启动。
+         * <p>
+         * 记录这个值的目的是,当用户向下滑动时,判断情况该回到这个位置还是关闭对话框,
+         * 并阻止当内容高度已经完全显示时的继续向上滑动操作。
+         */
+        public float bkgEnterAimY;
         
         
         @Override
         @Override
         public void init() {
         public void init() {
@@ -90,106 +99,13 @@ public class BottomDialog extends BaseDialog {
                     isShow = true;
                     isShow = true;
                     boxRoot.setAlpha(0f);
                     boxRoot.setAlpha(0f);
                     
                     
-                    scrollView.setOnTouchListener(new View.OnTouchListener() {
-                        @Override
-                        public boolean onTouch(View v, MotionEvent event) {
-                            switch (event.getAction()) {
-                                case MotionEvent.ACTION_DOWN:
-                                    svTouchDownY = event.getY();
-                                    isSvTouched = true;
-                                    break;
-                                case MotionEvent.ACTION_MOVE:
-                                    if (isSvTouched) {
-                                        if (scrollView.getScrollY() == 0) {
-                                            bkgTouchDownY = svTouchDownY;
-                                            bkg.setInterceptTouchEvent(true);
-                                            bkg.onTouchEvent(event);
-                                            isBkgTouched = true;
-                                            isInterceptTouched = true;
-                                            return true;
-                                        } else {
-                                            svTouchDownY = event.getY();
-                                            isInterceptTouched = false;
-                                        }
-                                    }
-                                    if (isInterceptTouched || bkg.getY() > 0) {
-                                        return true;
-                                    }
-                                    break;
-                                case MotionEvent.ACTION_UP:
-                                case MotionEvent.ACTION_CANCEL:
-                                    isInterceptTouched = false;
-                                    isSvTouched = false;
-                                    break;
-                            }
-                            return false;
-                        }
-                    });
+                    new BottomDialogTouchEventInterceptor(dialogImpl);
                     
                     
-                    bkg.setOnTouchListener(new View.OnTouchListener() {
-                        @Override
-                        public boolean onTouch(View v, MotionEvent event) {
-                            switch (event.getAction()) {
-                                case MotionEvent.ACTION_DOWN:
-                                    bkgTouchDownY = event.getY();
-                                    isBkgTouched = true;
-                                    break;
-                                case MotionEvent.ACTION_MOVE:
-                                    if (isBkgTouched) {
-                                        float aimY = bkg.getY() + event.getY() - bkgTouchDownY;
-                                        if (aimY < 0) {
-                                            bkg.setInterceptTouchEvent(false);
-                                            scrollView.onTouchEvent(event);
-                                            bkg.setY(0);
-                                        } else {
-                                            if (bkg.isChildScrollViewCanScroll()) {
-                                                bkg.setInterceptTouchEvent(true);
-                                                bkg.setY(aimY);
-                                            } else {
-                                                if (aimY > bkgEnterAimY) {
-                                                    bkg.setInterceptTouchEvent(true);
-                                                    bkg.setY(aimY);
-                                                }
-                                            }
-                                        }
-                                    }
-                                    break;
-                                case MotionEvent.ACTION_UP:
-                                case MotionEvent.ACTION_CANCEL:
-                                    isBkgTouched = false;
-                                    if (bkg.getY() > 0) {
-                                        if (bkg.getY() < bkgEnterAimY  + dip2px(15)) {
-                                            ObjectAnimator enterAnim = ObjectAnimator.ofFloat(bkg, "y", bkg.getY(), bkgEnterAimY);
-                                            enterAnim.setDuration(300);
-                                            enterAnim.start();
-                                        } else {
-                                            doDismiss(boxRoot);
-                                        }
-                                    }
-                                    break;
-                            }
-                            return true;
-                        }
-                    });
-                    scrollView.post(new Runnable() {
-                        @Override
-                        public void run() {
-                            bkg.setY(boxBkg.getHeight());
-                            if (bkg.isChildScrollViewCanScroll()) {
-                                bkgEnterAimY = boxBkg.getHeight() - bkg.getHeight() * 0.8f;
-                            } 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);
-                            
-                            bkg.setInterceptTouchEvent(true);
-                        }
-                    });
+                    boxContent.getViewTreeObserver().addOnGlobalLayoutListener(onContentViewLayoutChangeListener);
                     
                     
                     getDialogLifecycleCallback().onShow(me);
                     getDialogLifecycleCallback().onShow(me);
+                    
+                    onDialogInit(dialogImpl);
                 }
                 }
                 
                 
                 @Override
                 @Override
@@ -200,6 +116,23 @@ public class BottomDialog extends BaseDialog {
             });
             });
         }
         }
         
         
+        private ViewTreeObserver.OnGlobalLayoutListener onContentViewLayoutChangeListener = new ViewTreeObserver.OnGlobalLayoutListener() {
+            @Override
+            public void onGlobalLayout() {
+                if (boxContent != null) {
+                    float oldY = bkgEnterAimY;
+                    if (bkg.isChildScrollViewCanScroll()) {
+                        bkgEnterAimY = boxBkg.getHeight() - bkg.getHeight() * 0.6f;
+                    } else {
+                        bkgEnterAimY = boxBkg.getHeight() - bkg.getHeight();
+                    }
+                    ObjectAnimator enterAnim = ObjectAnimator.ofFloat(bkg, "y", oldY, bkgEnterAimY);
+                    enterAnim.setDuration(300);
+                    enterAnim.start();
+                }
+            }
+        };
+        
         @Override
         @Override
         public void refreshView() {
         public void refreshView() {
             txtDialogTitle.getPaint().setFakeBoldText(true);
             txtDialogTitle.getPaint().setFakeBoldText(true);
@@ -228,6 +161,9 @@ public class BottomDialog extends BaseDialog {
         public void doDismiss(View v) {
         public void doDismiss(View v) {
             if (v != null) v.setEnabled(false);
             if (v != null) v.setEnabled(false);
             
             
+            if (boxContent != null)
+                boxContent.getViewTreeObserver().removeOnGlobalLayoutListener(onContentViewLayoutChangeListener);
+            
             ObjectAnimator exitAnim = ObjectAnimator.ofFloat(bkg, "y", bkg.getY(), boxBkg.getHeight());
             ObjectAnimator exitAnim = ObjectAnimator.ofFloat(bkg, "y", bkg.getY(), boxBkg.getHeight());
             exitAnim.setDuration(300);
             exitAnim.setDuration(300);
             exitAnim.start();
             exitAnim.start();
@@ -241,6 +177,9 @@ public class BottomDialog extends BaseDialog {
         }
         }
     }
     }
     
     
+    protected void onDialogInit(DialogImpl dialog) {
+    }
+    
     public void refreshUI() {
     public void refreshUI() {
         if (dialogImpl == null) return;
         if (dialogImpl == null) return;
         dialogImpl.refreshView();
         dialogImpl.refreshView();

+ 97 - 0
DialogX/src/main/java/com/kongzue/dialogx/dialogs/BottomMenu.java

@@ -0,0 +1,97 @@
+package com.kongzue.dialogx.dialogs;
+
+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.R;
+import com.kongzue.dialogx.util.NormalMenuArrayAdapter;
+import com.kongzue.dialogx.util.views.BottomDialogListView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static android.view.View.OVER_SCROLL_NEVER;
+
+/**
+ * @author: Kongzue
+ * @github: https://github.com/kongzue/
+ * @homepage: http://kongzue.com/
+ * @mail: myzcxhh@live.cn
+ * @createTime: 2020/10/6 23:48
+ */
+public class BottomMenu extends BottomDialog {
+    
+    private OnIconChangeCallBack onIconChangeCallBack;
+    private BottomDialogListView listView;
+    private BaseAdapter menuArrayAdapter;
+    private List<CharSequence> menuList;
+    
+    @Override
+    protected void onDialogInit(final DialogImpl dialog) {
+        if (dialog != null) {
+            listView = new BottomDialogListView(getContext());
+            listView.setOverScrollMode(OVER_SCROLL_NEVER);
+            listView.setDivider(getResources().getDrawable(R.drawable.rect_dialogx_material_menu_split_divider));
+            listView.setDividerHeight(1);
+            RelativeLayout.LayoutParams listViewLp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+            dialog.boxCustom.addView(listView, listViewLp);
+            test();
+        }
+    }
+    
+    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();
+            }
+        });
+    }
+    
+    public OnIconChangeCallBack getOnIconChangeCallBack() {
+        return onIconChangeCallBack;
+    }
+    
+    public BottomMenu setOnIconChangeCallBack(OnIconChangeCallBack onIconChangeCallBack) {
+        this.onIconChangeCallBack = onIconChangeCallBack;
+        return this;
+    }
+    
+    public interface OnIconChangeCallBack {
+        int getIcon(int index, String menuText);
+    }
+}

+ 136 - 0
DialogX/src/main/java/com/kongzue/dialogx/util/BottomDialogTouchEventInterceptor.java

@@ -0,0 +1,136 @@
+package com.kongzue.dialogx.util;
+
+import android.animation.ObjectAnimator;
+import android.content.res.Resources;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.animation.DecelerateInterpolator;
+
+import com.kongzue.dialogx.dialogs.BottomDialog;
+import com.kongzue.dialogx.interfaces.DialogConvertViewInterface;
+import com.kongzue.dialogx.util.views.DialogXBaseRelativeLayout;
+
+/**
+ * @author: Kongzue
+ * @github: https://github.com/kongzue/
+ * @homepage: http://kongzue.com/
+ * @mail: myzcxhh@live.cn
+ * @createTime: 2020/10/7 4:01
+ */
+public class BottomDialogTouchEventInterceptor {
+    
+    /**
+     * 下边三个值用于判断触控过程,
+     * isBkgTouched:标记是否已按下
+     * bkgTouchDownY:记录起始触控位置
+     * scrolledY:记录 ScrollView 已滚动过的距离,下次触控事件将接着上次的位置继续滑动。
+     */
+    private boolean isBkgTouched = false;
+    private float bkgTouchDownY;
+    private float scrolledY;
+    /**
+     * 0:bkg接收触控事件,-1:scrollView进行滚动
+     * 此标记的意义在于,当从 [scrollView滚动] 与 [bkg接收触控事件] 状态切换时,
+     * 需要对bkgTouchDownY、scrolledY的值进行刷新,否则触控连续过程会出现闪跳。
+     */
+    private int oldMode;
+    
+    public BottomDialogTouchEventInterceptor(final BottomDialog.DialogImpl impl) {
+        
+        /**
+         * BottomDialog 触控事件说明:
+         * bkg 将拦截并接管所有触控操作。
+         * BottomDialog 的启动方式依据是内容布局高度是否大于可显示安全区域的高度。
+         * bkg 会在合适的时机,直接接管控制 ScrollView 的滚动。
+         * 因此,请确保内容布局的高度计算方式一定是按照内容高度计算,
+         * 即,请重写 onMeasure 方法:
+         * @Override
+         * protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+         *     int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
+         *     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;
+                        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();
+                                    aimY = impl.bkg.getY() + event.getY() - bkgTouchDownY;
+                                }
+                                
+                                if (impl.bkg.isChildScrollViewCanScroll()) {
+                                    impl.bkg.setY(aimY);
+                                } else {
+                                    if (aimY > impl.bkgEnterAimY) {
+                                        impl.bkg.setY(aimY);
+                                    }
+                                }
+                                
+                                oldMode = 0;
+                            }
+                        }
+                        break;
+                    case MotionEvent.ACTION_UP:
+                    case MotionEvent.ACTION_CANCEL:
+                        scrolledY = impl.scrollView.getScrollY();
+                        isBkgTouched = false;
+                        if (impl.bkg.getY() > 0) {
+                            if (impl.bkg.getY() < impl.bkgEnterAimY + dip2px(35)) {
+                                ObjectAnimator enterAnim = ObjectAnimator.ofFloat(impl.bkg, "y", impl.bkg.getY(), impl.bkgEnterAimY);
+                                enterAnim.setDuration(300);
+                                enterAnim.start();
+                            } else {
+                                impl.doDismiss(impl.boxRoot);
+                            }
+                        }
+                        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();
+                }
+                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);
+            }
+        });
+    }
+    
+    private int dip2px(float dpValue) {
+        final float scale = Resources.getSystem().getDisplayMetrics().density;
+        return (int) (dpValue * scale + 0.5f);
+    }
+}

+ 92 - 0
DialogX/src/main/java/com/kongzue/dialogx/util/NormalMenuArrayAdapter.java

@@ -0,0 +1,92 @@
+package com.kongzue.dialogx.util;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.kongzue.dialogx.R;
+import com.kongzue.dialogx.dialogs.BottomMenu;
+
+import java.util.List;
+
+/**
+ * @author: Kongzue
+ * @github: https://github.com/kongzue/
+ * @homepage: http://kongzue.com/
+ * @mail: myzcxhh@live.cn
+ * @createTime: 2020/10/7 0:00
+ */
+public class NormalMenuArrayAdapter extends ArrayAdapter {
+    
+    private BottomMenu.OnIconChangeCallBack onIconChangeCallBack;
+    public int resoureId;
+    public List<CharSequence> objects;
+    public Context context;
+    
+    public NormalMenuArrayAdapter(Context context, int resourceId, List<CharSequence> objects, BottomMenu.OnIconChangeCallBack onIconChangeCallBack) {
+        super(context, resourceId, objects);
+        this.objects = objects;
+        this.resoureId = resourceId;
+        this.context = context;
+        this.onIconChangeCallBack = onIconChangeCallBack;
+    }
+    
+    public class ViewHolder {
+        ImageView imgDialogxMenuIcon;
+        TextView txtDialogxMenuText;
+    }
+    
+    @Override
+    public int getCount() {
+        return objects.size();
+    }
+    
+    @Override
+    public CharSequence getItem(int position) {
+        return objects.get(position);
+    }
+    
+    @Override
+    public long getItemId(int position) {
+        return position;
+    }
+    
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        ViewHolder viewHolder = null;
+        if (convertView == null) {
+            viewHolder = new ViewHolder();
+            LayoutInflater mInflater = LayoutInflater.from(context);
+            convertView = mInflater.inflate(resoureId, null);
+            
+            viewHolder.imgDialogxMenuIcon = convertView.findViewById(R.id.img_dialogx_menu_icon);
+            viewHolder.txtDialogxMenuText = convertView.findViewById(R.id.txt_dialogx_menu_text);
+            
+            convertView.setTag(viewHolder);
+        } else {
+            viewHolder = (ViewHolder) convertView.getTag();
+        }
+        CharSequence text = objects.get(position);
+        if (null != text) {
+            viewHolder.txtDialogxMenuText.setText(text);
+            if (onIconChangeCallBack != null) {
+                int resId = onIconChangeCallBack.getIcon(position, text.toString());
+                if (resId != 0) {
+                    viewHolder.imgDialogxMenuIcon.setVisibility(View.VISIBLE);
+                    viewHolder.imgDialogxMenuIcon.setImageResource(resId);
+                } else {
+                    viewHolder.imgDialogxMenuIcon.setVisibility(View.GONE);
+                }
+            } else {
+                viewHolder.imgDialogxMenuIcon.setVisibility(View.GONE);
+            }
+        }
+        
+        return convertView;
+    }
+}

+ 41 - 0
DialogX/src/main/java/com/kongzue/dialogx/util/views/BottomDialogListView.java

@@ -0,0 +1,41 @@
+package com.kongzue.dialogx.util.views;
+
+import android.content.Context;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.widget.ListView;
+import android.widget.ScrollView;
+
+import androidx.annotation.RequiresApi;
+
+/**
+ * @author: Kongzue
+ * @github: https://github.com/kongzue/
+ * @homepage: http://kongzue.com/
+ * @mail: myzcxhh@live.cn
+ * @createTime: 2020/10/6 23:42
+ */
+public class BottomDialogListView extends ListView {
+    public BottomDialogListView(Context context) {
+        super(context);
+    }
+    
+    public BottomDialogListView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+    
+    public BottomDialogListView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+    
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
+        super.onMeasure(widthMeasureSpec, expandSpec);
+    }
+    
+}

+ 4 - 13
DialogX/src/main/java/com/kongzue/dialogx/util/views/MaxRelativeLayout.java

@@ -113,14 +113,6 @@ public class MaxRelativeLayout extends RelativeLayout {
         return this;
         return this;
     }
     }
     
     
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        if (onTouchListener!=null){
-            return onTouchListener.onTouch(this,event);
-        }
-        return super.onTouchEvent(event);
-    }
-    
     @Override
     @Override
     public boolean onInterceptTouchEvent(MotionEvent event) {
     public boolean onInterceptTouchEvent(MotionEvent event) {
         if (onTouchListener != null && interceptTouchEvent) {
         if (onTouchListener != null && interceptTouchEvent) {
@@ -142,10 +134,10 @@ public class MaxRelativeLayout extends RelativeLayout {
                         touchX = (int) event.getRawX();
                         touchX = (int) event.getRawX();
                     }
                     }
                     isMove = true;
                     isMove = true;
-                    
+                
                     float moveY = event.getRawY();
                     float moveY = event.getRawY();
                     float moveX = event.getRawX();
                     float moveX = event.getRawX();
-                    
+                
                     if (Math.abs(moveY - touchY) > dip2px(20) || Math.abs(moveX - touchX) > dip2px(20)) {
                     if (Math.abs(moveY - touchY) > dip2px(20) || Math.abs(moveX - touchX) > dip2px(20)) {
                         final ViewParent parent = getParent();
                         final ViewParent parent = getParent();
                         if (parent != null) {
                         if (parent != null) {
@@ -157,7 +149,7 @@ public class MaxRelativeLayout extends RelativeLayout {
             }
             }
             return isMove;
             return isMove;
         }
         }
-        return super.onInterceptTouchEvent(event);
+        return false;
     }
     }
     
     
     public boolean isChildScrollViewCanScroll() {
     public boolean isChildScrollViewCanScroll() {
@@ -172,8 +164,7 @@ public class MaxRelativeLayout extends RelativeLayout {
     
     
     private OnTouchListener onTouchListener;
     private OnTouchListener onTouchListener;
     
     
-    @Override
-    public void setOnTouchListener(OnTouchListener l) {
+    public void setTouchCallBack(OnTouchListener l) {
         onTouchListener = l;
         onTouchListener = l;
         super.setOnTouchListener(l);
         super.setOnTouchListener(l);
     }
     }

+ 11 - 0
DialogX/src/main/res/drawable/rect_dialogx_material_menu_split_divider.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/black10" />
+        </shape>
+    </item>
+
+</layer-list>

+ 32 - 0
DialogX/src/main/res/layout/item_dialogx_material_bottom_menu_normal_text.xml

@@ -0,0 +1,32 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="55dp"
+        android:gravity="center_vertical"
+        android:paddingLeft="20dp"
+        android:paddingRight="20dp">
+
+        <ImageView
+            android:id="@+id/img_dialogx_menu_icon"
+            android:layout_width="35dp"
+            android:layout_height="35dp"
+            android:layout_marginRight="10dp"
+            android:layout_marginLeft="-5dp"
+            android:padding="5dp"/>
+
+        <TextView
+            android:id="@+id/txt_dialogx_menu_text"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="left|center_vertical"
+            android:singleLine="true"
+            android:text=""
+            android:textColor="@color/black90"
+            android:textSize="16dp" />
+
+    </LinearLayout>
+
+</RelativeLayout>

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

@@ -31,7 +31,6 @@
                 android:layout_width="match_parent"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_marginTop="15dp"
                 android:layout_marginTop="15dp"
-                android:clickable="true"
                 android:orientation="vertical">
                 android:orientation="vertical">
 
 
                 <TextView
                 <TextView
@@ -56,6 +55,7 @@
                     android:scrollbars="vertical">
                     android:scrollbars="vertical">
 
 
                     <LinearLayout
                     <LinearLayout
+                        android:id="@+id/box_content"
                         android:layout_width="match_parent"
                         android:layout_width="match_parent"
                         android:layout_height="wrap_content"
                         android:layout_height="wrap_content"
                         android:orientation="vertical">
                         android:orientation="vertical">

+ 28 - 0
app/src/main/java/com/kongzue/dialogxdemo/MainActivity.java

@@ -18,6 +18,7 @@ import com.kongzue.baseframework.util.CycleRunner;
 import com.kongzue.baseframework.util.JumpParameter;
 import com.kongzue.baseframework.util.JumpParameter;
 import com.kongzue.dialogx.DialogX;
 import com.kongzue.dialogx.DialogX;
 import com.kongzue.dialogx.dialogs.BottomDialog;
 import com.kongzue.dialogx.dialogs.BottomDialog;
+import com.kongzue.dialogx.dialogs.BottomMenu;
 import com.kongzue.dialogx.dialogs.InputDialog;
 import com.kongzue.dialogx.dialogs.InputDialog;
 import com.kongzue.dialogx.dialogs.MessageDialog;
 import com.kongzue.dialogx.dialogs.MessageDialog;
 import com.kongzue.dialogx.dialogs.TipDialog;
 import com.kongzue.dialogx.dialogs.TipDialog;
@@ -250,6 +251,33 @@ public class MainActivity extends BaseActivity {
                 new BottomDialog().show();
                 new BottomDialog().show();
             }
             }
         });
         });
+        
+        btnBottomMenu.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                new BottomMenu().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();
+            }
+        });
     }
     }
     
     
     @Override
     @Override

+ 36 - 23
app/src/main/res/layout/activity_main.xml

@@ -362,7 +362,7 @@
                     android:layout_width="wrap_content"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_marginTop="15dp"
                     android:layout_marginTop="15dp"
-                    android:text="其他功能演示"
+                    android:text="底部菜单"
                     android:textColor="#dc000000"
                     android:textColor="#dc000000"
                     android:textSize="14dp"
                     android:textSize="14dp"
                     android:textStyle="bold" />
                     android:textStyle="bold" />
@@ -373,56 +373,40 @@
                     android:orientation="horizontal">
                     android:orientation="horizontal">
 
 
                     <TextView
                     <TextView
-                        android:id="@+id/btn_showBreak"
+                        android:id="@+id/btn_bottom_dialog"
                         android:layout_width="wrap_content"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:layout_height="wrap_content"
                         android:layout_margin="5dp"
                         android:layout_margin="5dp"
                         android:background="@drawable/rect_button"
                         android:background="@drawable/rect_button"
                         android:paddingHorizontal="15dp"
                         android:paddingHorizontal="15dp"
                         android:paddingVertical="10dp"
                         android:paddingVertical="10dp"
-                        android:text="显示Dialog时关闭Activity"
+                        android:text="底部对话框"
                         android:textColor="@color/white"
                         android:textColor="@color/white"
                         android:textSize="13dp"
                         android:textSize="13dp"
                         android:textStyle="bold" />
                         android:textStyle="bold" />
 
 
-                </LinearLayout>
-
-                <TextView
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="15dp"
-                    android:text="底部菜单"
-                    android:textColor="#dc000000"
-                    android:textSize="14dp"
-                    android:textStyle="bold" />
-
-                <LinearLayout
-                    android:layout_width="match_parent"
-                    android:layout_height="wrap_content"
-                    android:orientation="horizontal">
-
                     <TextView
                     <TextView
-                        android:id="@+id/btn_bottom_dialog"
+                        android:id="@+id/btn_bottom_menu"
                         android:layout_width="wrap_content"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:layout_height="wrap_content"
                         android:layout_margin="5dp"
                         android:layout_margin="5dp"
                         android:background="@drawable/rect_button"
                         android:background="@drawable/rect_button"
                         android:paddingHorizontal="15dp"
                         android:paddingHorizontal="15dp"
                         android:paddingVertical="10dp"
                         android:paddingVertical="10dp"
-                        android:text="标题对话框"
+                        android:text="底部菜单"
                         android:textColor="@color/white"
                         android:textColor="@color/white"
                         android:textSize="13dp"
                         android:textSize="13dp"
                         android:textStyle="bold" />
                         android:textStyle="bold" />
 
 
                     <TextView
                     <TextView
-                        android:id="@+id/btn_bottom_menu"
+                        android:id="@+id/btn_bottom_reply"
                         android:layout_width="wrap_content"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:layout_height="wrap_content"
                         android:layout_margin="5dp"
                         android:layout_margin="5dp"
                         android:background="@drawable/rect_button"
                         android:background="@drawable/rect_button"
                         android:paddingHorizontal="15dp"
                         android:paddingHorizontal="15dp"
                         android:paddingVertical="10dp"
                         android:paddingVertical="10dp"
-                        android:text="显示底部菜单"
+                        android:text="底部输入框"
                         android:textColor="@color/white"
                         android:textColor="@color/white"
                         android:textSize="13dp"
                         android:textSize="13dp"
                         android:textStyle="bold" />
                         android:textStyle="bold" />
@@ -561,6 +545,35 @@
                         android:textStyle="bold" />
                         android:textStyle="bold" />
 
 
                 </LinearLayout>
                 </LinearLayout>
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="15dp"
+                    android:text="其他功能演示"
+                    android:textColor="#dc000000"
+                    android:textSize="14dp"
+                    android:textStyle="bold" />
+
+                <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal">
+
+                    <TextView
+                        android:id="@+id/btn_showBreak"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:layout_margin="5dp"
+                        android:background="@drawable/rect_button"
+                        android:paddingHorizontal="15dp"
+                        android:paddingVertical="10dp"
+                        android:text="显示Dialog时关闭Activity"
+                        android:textColor="@color/white"
+                        android:textSize="13dp"
+                        android:textStyle="bold" />
+
+                </LinearLayout>
             </LinearLayout>
             </LinearLayout>
 
 
         </ScrollView>
         </ScrollView>

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


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


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


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


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


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


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


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


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


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


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


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


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