Skip to content

Android一个简单强大的弹框处理框架,支持链式调用,提供了比较全面的api,并且覆盖Android几乎所有的弹框类型,如Dialog、BottomSheetDialog、DialogFragment、BottomSheetDialogFragment、PopupWindow、DialogActivity,总结起来就是调用简单、功能强大。

Notifications You must be signed in to change notification settings

huangxiaolianghh/MTPopup

Repository files navigation

MTPopup


Android一个简单强大的弹框处理框架,支持链式调用,提供了比较全面的api,并且覆盖Android几乎所有的弹框类型,如Dialog、BottomSheetDialog、DialogFragment、BottomSheetDialogFragment、PopupWindow、DialogActivity,总结起来就是调用简单、功能强大。

功能特点

  • 层次结构分明,分工明确
  • 采用链式调用一点到底
  • 支持Android多种弹框:DialogBottomSheetDialogDialogFragmentBottomSheetDialogFragmentPopupWindowDialogActivity
  • 支持设置弹窗的主题样式、宽高(最大宽高及屏幕宽高比等)、背景透明度、圆角、显示位置、显示消失动画
  • 支持设置弹窗ContentView相关控件View的属性,如点击、长按事件等
  • 支持设置弹窗关闭的逻辑,如返回键、点击外部空白区域
  • 支持设置弹窗的显示及关闭事件监听
  • 支持设置弹窗自动消失
  • 支持Liffecycle设置,生命周期监听
  • ktx版本更新中...
  • ...

项目引入该库

在你的 Project build.gradle文件中添加:

allprojects {
		repositories {
			...
			maven { url 'https://jitpack.io' }
		}
	}

在你的 Module build.gradle文件中添加:

dependencies {
	        implementation 'com.github.huangxiaolianghh.MTPopup:popup:1.0.2'
	}

如何调用

我们可以通过PopupCompat asXXX系列的方法来展示不同的弹框类型,如:

  • asDialog
  • asBottomSheetDialog
  • asDialogFragment
  • asBottomSheetDialogFragment
  • asPopupWindow
  • asDialogActivity

下面以展示Dialog进行说明:

            PopupCompat.get().asDialog(DialogDemoActivity.this)
                    .themeStyle(R.style.MTPopup_Dialog)   //主题样式
                    .view(R.layout.popup_test)            //可传View
                    .radius(50)                           //设置四个圆角
//                    //设置弹窗上(下、左、右)方圆角,
//                    .radiusSideTop(50)
                    .animStyle(R.style.PopupEnterExpandExitShrinkAnimation)  //动画
                    //宽高比
//                    .widthInPercent(0.8f)
//                    .heightInPercent(0.8f)
//                    //最大宽高
//                    .maxWidth(800)
//                    .maxHeight(800)
//                    //框架默认是width=ViewGroup.LayoutParams.MATCH_PARENT,height=ViewGroup.LayoutParams.WRAP_CONTENT
//                    .width(ViewGroup.LayoutParams.MATCH_PARENT)
//                    .height(ViewGroup.LayoutParams.WRAP_CONTENT)
//                    .matchHeight()
//                    .matchWidth()
//                    .wrapHeight()
                    .wrapWidth()
                    .dimAmount(0f)                       //不设置背景透明度,默认0.5f
                    .cancelable(false)                   //返回键dismiss
                    .cancelableOutside(false)            //点击外部区域dismiss
                    .autoDismissTime(5000)               //5秒后自动dismiss
                    .gravity(Gravity.CENTER)             //设置显示位置
                    //添加View点击事件,也支持添加多个View的点击事件
                    .clickListener(R.id.btn_left, (popupInterface, view, holder) -> {
                        popupInterface.dismiss();
                        Toast.makeText(
                                DialogDemoActivity.this,
                                "点击了" + ((Button) holder.getView(R.id.btn_left)).getText(),
                                Toast.LENGTH_SHORT)
                                .show();
                    })
                    .clickListener(R.id.btn_right, (popupInterface, view, holder) -> popupInterface.dismiss())
                    //添加多个View长按事件,也支持添加单个View的点击事件
                    .longClickIds(R.id.btn_left, R.id.btn_right)
                    .longClickIdsListener((popupInterface, view, holder) -> {
                        if (view.getId() == R.id.btn_left) {
                            Toast.makeText(
                                    DialogDemoActivity.this,
                                    "长按了" + ((Button) holder.getView(R.id.btn_left)).getText(),
                                    Toast.LENGTH_SHORT)
                                    .show();
                        } else if (view.getId() == R.id.btn_right) {
                            Toast.makeText(
                                    DialogDemoActivity.this,
                                    "长按了" + ((Button) holder.getView(R.id.btn_right)).getText(),
                                    Toast.LENGTH_SHORT)
                                    .show();
                        }
                        return true;
                    })
                    //关闭事件监听
                    .dismissListener(popupInterface ->
                            Toast.makeText(
                                    DialogDemoActivity.this,
                                    "消失监听",
                                    Toast.LENGTH_SHORT)
                                    .show())
                    //显示事件监听
                    .showListener(popupInterface ->
                            Toast.makeText(
                                    DialogDemoActivity.this,
                                    "显示监听",
                                    Toast.LENGTH_SHORT)
                                    .show())
                    //View绑定事件监听
                    .bindViewListener((PopupViewHolder holder) -> {
                        //holder可以对象弹窗所有控件操作,在这里处理弹窗内部相关逻辑
                        holder.setText(R.id.tv_popup_title, "MTPopup");
                    })
                    .create().show();

如果我们需要在弹窗展示期间改变ContentView一些控件的属性,这时我们可以经过Config配置对象的create()方法获取Popup对象实例,通过其就可以拿到ContentView的XPopupViewHolder对象,进而改变相关控件的属性,如:

            Popup<DialogDelegate> popup = PopupCompat.get().asDialog(DialogDemoActivity.this)
                    .view(R.layout.popup_test)
                    .gravity(Gravity.CENTER)
                    .clickListener(R.id.btn_right, (popupInterface, view, holder) -> popupInterface.dismiss())
                    .cancelableOutside(true)
                    .create();
            popup.show();
            new Handler(Looper.getMainLooper()).postDelayed(() ->
                    popup.getPopupViewHolder().setText(R.id.tv_popup_title, "获取Popup对象,更新标题"), 5000);

MTPopup实现了lifecycle,添加被观察者和实现PopupLifecycleObserver接口即可,如:

            PopupCompat.get().asDialog(DialogDemoActivity.this)
                    .view(R.layout.popup_test)
                    .gravity(Gravity.BOTTOM)
                    .cancelable(false)
                    .cancelableOutside(false)
                    .observeOn(getLifecycle(), new PopupLifecycleObserver<DialogDelegate>() {
                        @Override
                        public void onPause(IPopup<DialogDelegate> popup) {
                            popup.dismiss();
                            Toast.makeText(
                                    DialogDemoActivity.this,
                                    "onPause-->消失监听",
                                    Toast.LENGTH_SHORT)
                                    .show();
                        }
                    })
                    .create()
                    .show();

这里只重写了onPause(),其它生命周期的回调直接重写即可。

对于Dialog,如果Activity关闭前并没有关闭dialog,则会造成内存泄漏,这里我们简单实现了onDestroy()关闭dialog的开关方法:observeOn(Lifecycle lifecycle, boolean dismissObserverOnDestroy),如:

            PopupCompat.get().asDialog(DialogDemoActivity.this)
                    .view(R.layout.popup_test)
                    .gravity(Gravity.BOTTOM)
                    .cancelable(false)
                    .cancelableOutside(false)
                    .clickListener(R.id.btn_right, (popupInterface, view, holder) -> finish())
                    .bindViewListener(holder -> holder.setText(R.id.btn_right, "关闭页面"))
                    .observeOn(getLifecycle(), true)
                    .create()
                    .show();

这里特别说明下Popup dismiss掉,会把代理delegate释放,也会将观察者的关系解除,此时的Popup对象就没有作用,调用里面的方法会抛异常!若想再次使用,直接调用Config的create()方法重新初始化Popup对象。

因为Popup实现了LifecycleObserver观察者,这意味着这几种弹窗类型都可以感知被观察者的生命周期,Dialog感知宿主的生命周期对我们来说是非常有意义的事情,而其它弹窗类型我们可以酌情使用LifecycleObserver,归根结底,我们要懂得LifecycleObserver的原理才不会出错。

至于其它类型弹框的使用和动画的设置可以通过demo去了解,这里就不细说了。

MTPopup属性配置说明

基本公共属性

属性 设置方法 说明
mContext 构造函数BaseConfig(Context context) 上下文
mLifecycle
mPopupLifecycleObserver
mDismissObserverOnDestroy
observeOn(Lifecycle lifecycle, PopupLifecycleObserver popupLifecycleObserver)
observeOn(Lifecycle lifecycle, boolean dismissObserverOnDestroy)
被观察者生命周期的回调
设置onDestroy()回调关闭Popup的开关
mThemeStyle themeStyle(@StyleRes int themeStyle) 主题样式,PopupWindow不支持此属性
mAnimStyle animStyle(@StyleRes int animStyle) 动画
mContentView view(View contentView)
view(@LayoutRes int contentViewResId)
内容View
mOnBindViewListener bindViewListener(PopupInterface.OnBindViewListener listener) View绑定到Popup前的监听器
mOnShowListener showListener(PopupInterface.OnShowListener onShowListener) Popup显示监听器
mOnDismissListener dismissListener(PopupInterface.OnDismissListener onDismissListener) Popup关闭监听器
mClickIds clickIds(@IdRes int... clickIds) 点击控件id集合
mOnClickListener clickIdsListener(@NonNull PopupInterface.OnClickListener onClickListener) 控件点击事件监听器
mLongClickIds longClickIds(@IdRes int... longClickIds) 长按控件id集合
mOnLongClickListener longClickIdsListener(@NonNull PopupInterface.OnLongClickListener onLongClickListener) 控件长按事件监听器
mWidth width(int width)
matchWidth()
wrapWidth()
宽,默认ViewGroup.LayoutParams.MATCH_PARENT
mHeight height(int height)
matchHeight()
wrapHeight()
高,默认ViewGroup.LayoutParams.WRAP_CONTENT
mMaxWidth maxWidth(int maxWidth) 最大宽
mMaxHeight maxHeight(int maxHeight) 最大高
mWidthInPercent widthInPercent(float widthInPercent) 屏幕宽度比
mHeightInPercent heightInPercent(float heightInPercent) 屏幕高度比
mGravity gravity(int gravity) 弹窗位置,BottomSheet系列弹窗的位置恒为Gravity.BOTTOM
mBackgroundDrawable backgroundDrawable(Drawable backgroundDrawable) 弹窗window的背景
mDimAmount dimAmount(float dimAmount) 弹窗周围的亮度,默认0.5f
mAutoDismissTime autoDismissTime(long autoDismissTime) x秒后自动消失
mCancelable cancelable(boolean cancelable) 返回键事件关闭弹窗,默认true,对于PopupWindow无效,调用者自行处理其此事件
mCancelableOutside cancelableOutside(boolean cancelableOutside) 点击外部区域关闭弹窗,默认true
mRadius
mRadiusSideLeft
mRadiusSideTop
mRadiusSideRight
mRadiusSideBottom
radius(int radius)
radiusSideLeft(int radiusSideLeft)
radiusSideTop(int radiusSideTop)
radiusSideRight(int radiusSideRight)
radiusSideBottom(int radiusSideBottom)
圆角
左边圆角
上边圆角
右边圆角
下边圆角

这里只列举MTPopup的公共属性,至于不同的弹窗类型,其对应的Config定义了特有的属性,这里就不列举出来了,详细的属性可以去看XXXConfig系列源码。

我的博客 MTPopup,Android一个简单强大的弹框

About

Android一个简单强大的弹框处理框架,支持链式调用,提供了比较全面的api,并且覆盖Android几乎所有的弹框类型,如Dialog、BottomSheetDialog、DialogFragment、BottomSheetDialogFragment、PopupWindow、DialogActivity,总结起来就是调用简单、功能强大。

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published