断断续续地,利用工作之余的不少时间归纳整合了这个MTPopup。虽然没啥高深的技术,但是我认为这个库能给大家在项目上的弹框处理带来些许的方便,使用它,大家就不必频繁的新建class文件,频繁地写重复代码,直接链式调用,提供全面的api,应该能满足项目上绝大多数的业务,并且覆盖了Android所有的弹框类型(Dialog、BottomSheetDialog、DialogFragment、BottomSheetDialogFragment、PopupWindow、DialogActivity),总结起来就是调用简单、功能强大。
下一步计划添加弹窗的优先级队列和全局弹窗,有什么好的建议和想法也可以提出来!!
在你的 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系列的方法来展示不同的弹框类型,如:
下面以展示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的PopupViewHolder对象,进而改变相关控件的属性,如:
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);
框架的普通Dialog和DialogActivity默认实现的主题样式:R.style.MTPopup_Dialog
<!-- 普通Dialog主题样式 -->
<style name="MTPopup.Dialog" parent="Theme.MaterialComponents.DayNight.Dialog">
<item name="android:windowNoTitle">true</item>
<!-- 是否不显示title 继承AppCompat样式-->
<item name="windowNoTitle">true</item>
<!-- 设置dialog显示区域外部的背景(透明),有圆角,圆角外部区域显示这个颜色 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 设置dialog的背景(透明),此颜色值会覆盖掉windowBackground的值 -->
<item name="android:background">@android:color/transparent</item>
<item name="android:colorBackground">@android:color/transparent</item>
<!-- 设置灰度的值,为1时,除Dialog内容布局高亮其它全黑,系统的默认值是0.6 -->
<item name="android:backgroundDimAmount">0.5</item>
<!-- 是否允许背景灰暗,即是否让显示区域以外使用上面设置的黑色半透明背景,设为false时,等价于backgroundDimAmount=0 -->
<item name="android:backgroundDimEnabled">true</item>
<!-- 是否有遮盖 -->
<item name="android:windowContentOverlay">@null</item>
<!-- 设置Dialog的windowFrame框(无) -->
<item name="android:windowFrame">@null</item>
<!-- 是否浮现在activity之上,必须设为true,否则自己独立占一个界面,这根本就不像是一个对话框了 -->
<item name="android:windowIsFloating">true</item>
<!-- 是否半透明,貌似没什么卵用 -->
<item name="android:windowIsTranslucent">true</item>
</style>
BottomSheetDialog默认实现的主题样式:R.style.MTPopup_BottomSheetDialog
<!-- BottomSheetDialog样式 -->
<style name="MTPopup.BottomSheetDialog" parent="Theme.Design.BottomSheetDialog">
<item name="android:windowNoTitle">true</item>
<!-- 是否不显示title 继承AppCompat样式-->
<item name="windowNoTitle">true</item>
<!-- 设置dialog显示区域外部的背景(透明),有圆角,圆角外部区域显示这个颜色 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 设置dialog的背景(透明),此颜色值会覆盖掉windowBackground的值 -->
<item name="android:background">@android:color/transparent</item>
<item name="android:colorBackground">@android:color/transparent</item>
<!-- 设置灰度的值,为1时,除Dialog内容布局高亮其它全黑,系统的默认值是0.6 -->
<item name="android:backgroundDimAmount">0.5</item>
<!-- 是否允许背景灰暗,即是否让显示区域以外使用上面设置的黑色半透明背景,设为false时,等价于backgroundDimAmount=0 -->
<item name="android:backgroundDimEnabled">true</item>
<!-- 是否有遮盖 -->
<item name="android:windowContentOverlay">@null</item>
<!-- 设置Dialog的windowFrame框(无) -->
<item name="android:windowFrame">@null</item>
<!-- 是否浮现在activity之上,必须设为true,否则自己独立占一个界面,这根本就不像是一个对话框了 -->
<item name="android:windowIsFloating">true</item>
<!-- 是否半透明,貌似没什么卵用 -->
<item name="android:windowIsTranslucent">true</item>
</style>
DialogActivity动画设置:
<!-- 自定义DialogActivity动画 -->
<style name="ActivityEnterRightExitLeftAnimation">
<item name="android:activityOpenEnterAnimation">@anim/in_from_right</item>
<item name="android:activityOpenExitAnimation">@null</item>
<item name="android:activityCloseEnterAnimation">@null</item>
<item name="android:activityCloseExitAnimation">@anim/out_to_left</item>
</style>
其它弹窗的动画设置:
<style name="PopupEnterExpandExitShrinkAnimation">
<item name="android:windowEnterAnimation">@anim/enter_folds_expand</item>
<item name="android:windowExitAnimation">@anim/exit_folds_shrink</item>
</style>
具体的设置可参考项目demo,这里就不细说了。
基本公共属性
属性 | 设置方法 | 说明 |
---|---|---|
mContext | 构造函数BaseConfig(Context context) | 上下文 |
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) | 弹窗周围的亮度 |
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几乎所有的弹窗类型,主要是为了简化弹窗的处理方式,直接链式调用,发布这个初版基本能满足大多数业务场景。接下来自己也会继续完善这个库,将弹窗优先级和全局弹窗功能加进来,当然DialogActivity也可以实现不依赖Activity的全局弹窗,自己一个人的力量有限,MTPopup可能有些功能设计考虑的不是很充分,难免会有些错误,希望大家在使用中能多多提点意见,自己也会努力去改进和完善。
最后欢迎大家start!