73

GitHub - li-xiaojun/XPopup: 功能强大,UI简洁,交互优雅的通用弹窗!可以替代Dialog...

 5 years ago
source link: https://github.com/li-xiaojun/XPopup
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

README.md

XPopup

功能强大,UI简洁,交互优雅的通用弹窗!可以替代Dialog,PopupWindow,PopupMenu,BottomSheet等组件,自带十几种效果良好的动画, 支持完全的UI和动画自定义!

编写本库的初衷有以下几点:

  1. 项目有这样常见需求:中间和底部弹出甚至可拖拽的对话框,指定位置的PopupMenu或者PopupWindow,指定区域阴影的弹出层效果
  2. 市面上已有的类库要么功能不足够,要么交互效果不完美,有着普遍的缺点,就像BottomSheet存在的问题一样。比如:窗体消失的动画和背景渐变动画不一致,窗体消失后半透明背景仍然停留一会儿

设计思路: 综合常见的弹窗场景,我将其分为3类:

  1. Center类型,就是在中间弹出的弹窗,比如确认和取消弹窗,Loading弹窗
  2. Bottom类型,就是从页面底部弹出,比如从底部弹出的分享窗体,知乎的从底部弹出的评论列表
  3. Attach类型,就是弹窗的位置需要依附于某个View,就像系统的PopupMenu效果一样,但PopupMenu的自定义性很差

尽管我已经内置了几种常见弹窗的实现,但不可能满足所有的需求,你很可能需要自定义;你自定义的弹窗类型应该属于这3种之一。

动画设计: 为了增加交互的趣味性,遵循Material Design,在设计动画的时候考虑了很多细节,过渡,层级的变化。具体可以从Demo中感受。

Gradle

implementation 'com.lxj:xpopup:latest release'

ScreenShot

使用

为了方便使用,已经内置了几种常见弹窗的实现:

  1. 显示确认和取消对话框

    XPopup.get(getContext()).asConfirm("我是标题", "我是内容",
                            new OnConfirmListener() {
                                @Override
                                public void onConfirm() {
                                   toast("click confirm");
                                }
                            })
                            .show();
  2. 显示带输入框的确认和取消对话框

    XPopup.get(getContext()).asInputConfirm("我是标题", "请输入内容。",
                            new OnInputConfirmListener() {
                                @Override
                                public void onConfirm(String text) {
                                    toast("input text: " + text);
                                }
                            })
                            .show();
  3. 显示中间弹出的列表弹窗

    XPopup.get(getActivity()).asCenterList("请选择一项",new String[]{"条目1", "条目2", "条目3", "条目4"},
                            new OnSelectListener() {
                                @Override
                                public void onSelect(int position, String text) {
                                    toast("click "+text);
                                }
                            })
                            .show();
  4. 显示中间弹出的加载框

    XPopup.get(getActivity()).asLoading().show();
  5. 显示从底部弹出的列表弹窗

    XPopup.get(getActivity()).asBottomList("请选择一项",new String[]{"条目1", "条目2", "条目3", "条目4","条目5"},
                            new OnSelectListener() {
                                @Override
                                public void onSelect(int position, String text) {
                                    toast("click "+text);
                                }
                            })
                            .show();
  6. 显示依附于某个View的弹窗

    XPopup.get(getActivity()).asAttachList(new String[]{"分享", "编辑", "不带icon"},
                            new int[]{R.mipmap.ic_launcher, R.mipmap.ic_launcher},
                            new OnSelectListener() {
                                @Override
                                public void onSelect(int position, String text) {
                                    toast("click "+text);
                                }
                            })
                            .atView(v)  // 依附于所点击的View,必须设置
                            .show();
  7. 关闭弹窗

    XPopup.get(getContext()).dismiss();
  8. 自定义弹窗

    当你自定义弹窗的时候,需要选择继承CenterPopupViewBottomPopupView或者AttachPopupView三者之一。假设需要自定义Center类型的弹窗:

    class CustomPopup extends CenterPopupView{
            public CustomPopup(@NonNull Context context) {
                super(context);
            }
            // 返回自定义弹窗的布局
            @Override
            protected int getImplLayoutId() {
                return R.layout.custom_popup;
            }
            // 执行初始化操作,比如:findView,设置点击,或者任何你弹窗内的业务逻辑
            @Override
            protected void initPopupContent() {
                super.initPopupContent();
                findViewById(R.id.tv_close).setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        dismiss(); // 关闭弹窗
                    }
                });
            }
            // 设置最大宽度,看需要而定
            @Override
            protected int getMaxWidth() {
                return super.getMaxWidth();
            }
            // 设置最大高度,看需要而定
            @Override
            protected int getMaxHeight() {
                return super.getMaxHeight();
            }
            // 设置自定义动画器,看需要而定
            @Override
            protected PopupAnimator getPopupAnimator() {
                return super.getPopupAnimator();
            }
        }

    使用自定义弹窗:

    XPopup.get(getContext())
            .asCustom(new CustomPopup(getContext()))
            .show();
  9. 自定义动画

    自定义动画已经被设计得非常简单,动画和弹窗是无关的;这意味着你可以将动画设置给内置弹窗或者自定义弹窗。继承PopupAnimator,实现3个方法:

    • 如何初始化动画
    • 动画如何开始
    • 动画如何结束

    比如:自定义一个旋转的动画:

    class RotateAnimator extends PopupAnimator{
            @Override
            public void initAnimator() {
                targetView.setScaleX(0);
                targetView.setScaleY(0);
                targetView.setAlpha(0);
                targetView.setRotation(360);
            }
            @Override
            public void animateShow() {
                targetView.animate().rotation(0).scaleX(1).scaleY(1).alpha(1).setInterpolator(new FastOutSlowInInterpolator()).setDuration(animateDuration).start();
            }
            @Override
            public void animateDismiss() {
                targetView.animate().rotation(360).scaleX(0).scaleY(0).alpha(0).setInterpolator(new FastOutSlowInInterpolator()).setDuration(animateDuration).start();
            }
        }

    使用自定义动画:

    XPopup.get(getContext())
            .asConfirm(...)
            .customAnimator(new RotateAnimator())
            .show();
  10. 其他

  • 设置主色调

    默认情况下,XPopup的主色为灰色,这体现在Button和EditText的颜色上。因为XPopup是单例,所以主色调只需要设置一次即可,可以放在Application中设置。

    XPopup.get(this).setPrimaryColor(getResources().getColor(R.color.colorPrimary));
  • 其他设置

    XPopup.get(this)
        .hasShadowBg(true) // 是否有半透明的背景,默认为true
        .dismissOnBackPressed(true) // 按返回键是否关闭弹窗,默认为true
        .dismissOnTouchOutside(true) // 点击外部是否关闭弹窗,默认为true
        .popupAnimation(PopupAnimation.ScaleAlphaFromCenter) // 设置内置的动画
        .customAnimator(null) // 设置自定义的动画器

待办

  • Bottom类型的弹出支持手势拖拽,就像知乎的评论弹窗那样
  • 手指长按弹出弹窗,就像微信的列表长按效果
  • 局部阴影覆盖的弹窗,就像淘宝的商品列表筛选框那样
  • DrawerLayout效果,就像从左边或右边打开的DrawerLayout那样

Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK