IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> XPopUp,Android一个简单强大的弹框 -> 正文阅读

[移动开发]XPopUp,Android一个简单强大的弹框

前言

断断续续地,利用工作之余的不少时间归纳整合了这个XPopUp。虽然没啥高深的技术,但是我认为这个库能给大家在项目上的弹框处理带来些许的方便,使用它,大家就不必频繁的新建class文件,频繁地写重复代码,直接链式调用,提供全面的api,应该能满足项目上绝大多数的业务,并且覆盖了Android所有的弹框类型(DialogBottomSheetDialogDialogFragmentBottomSheetDialogFragmentPopupWindowDialogActivity),总结起来就是调用简单、功能强大。


功能特点

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

下一步计划添加弹窗的优先级队列和全局弹窗,有什么好的建议和想法也可以提出来!!


设计实现

  • XPopupCompat 单例实现的XPopup管理类
  • XPopup 弹窗实体,所有的弹窗类型对象都可以认为是一个XPopup,里面维护了弹窗的Config和Delegate对象
  • XPopupInterface XPopup的抽象接口类
  • Config 弹窗的配置对象,不同的弹窗类型有不同的Config对象,负责存储弹窗的相关属性,如DialogConfigDialogFragmentConfig
  • Delegate 弹窗的代理对象,不同的弹窗类型有不同的Delegate对象,负责处理弹窗的相关属性,如DialogDelegateDialogFragmentDelegate
  • XPopupRootView 弹窗的RoottView
  • XPopupViewHolder 处理弹窗ContentView的Holder对象,类似RecyclerView的BaseViewHolder

项目引入该库

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

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

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

dependencies {
	        implementation 'com.github.HHotHeart:XPopUp:1.0.0'
	}

如何使用

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

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

下面以展示Dialog进行说明:

            XPopupCompat.get().asDialog(DialogDemoActivity.this)
                    .themeStyle(R.style.XPopup_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()
                    .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();
                    })
                    //添加多个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((XPopupViewHolder holder) -> {
                        //holder可以对象弹窗所有控件操作,在这里处理弹窗内部相关逻辑
                        holder.setText(R.id.tv_popup_title, "XPopup");
                    })
                    .create()
                    .show();

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

            XPopup<DialogConfig, DialogDelegate> xPopup = XPopupCompat.get().asDialog(DialogDemoActivity.this)
                    .view(R.layout.popup_test)
                    .gravity(Gravity.BOTTOM)
                    .autoDismissTime(10000)
                    .create();
            xPopup.show();
            new Handler(Looper.getMainLooper()).postDelayed(() ->
                    xPopup.getPopupViewHolder().setText(R.id.tv_popup_title, "获取xPopup对象,更新标题"), 5000);

框架的普通Dialog和DialogActivity默认实现的主题样式:R.style.XPopup_Dialog


    <!-- 普通Dialog主题样式 -->
    <style name="XPopup.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.XPopup_BottomSheetDialog

    <!--  BottomSheetDialog样式  -->
    <style name="XPopup.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,这里就不细说了。

XPopUp属性配置说明

基本公共属性

属性设置方法说明
mContext构造函数BaseConfig(Context context)上下文
mThemeStylethemeStyle(@StyleRes int themeStyle)主题样式,PopupWindow不支持此属性
mAnimStyleanimStyle(@StyleRes int animStyle)动画
mContentViewview(View contentView)
view(@LayoutRes int contentViewResId)
内容View
mOnBindViewListenerbindViewListener(XPopupInterface.OnBindViewListener listener)View绑定到XPopup前的监听器
mOnShowListenershowListener(XPopupInterface.OnShowListener onShowListener)XPopup显示监听器
mOnDismissListenerdismissListener(XPopupInterface.OnDismissListener onDismissListener)XPopup关闭监听器
mClickIdsclickIds(@IdRes int… clickIds)点击控件id集合
mOnClickListenerclickIdsListener(@NonNull XPopupInterface.OnClickListener onClickListener)控件点击事件监听器
mLongClickIdslongClickIds(@IdRes int… longClickIds)长按控件id集合
mOnLongClickListenerlongClickIdsListener(@NonNull XPopupInterface.OnLongClickListener onLongClickListener)控件长按事件监听器
mWidthwidth(int width)
matchWidth()
wrapWidth()
宽,默认ViewGroup.LayoutParams.MATCH_PARENT
mHeightheight(int height)
matchHeight()
wrapHeight()
高,默认ViewGroup.LayoutParams.WRAP_CONTENT
mMaxWidthmaxWidth(int maxWidth)最大宽
mMaxHeightmaxHeight(int maxHeight)最大高
mWidthInPercentwidthInPercent(float widthInPercent)屏幕宽度比
mHeightInPercentheightInPercent(float heightInPercent)屏幕高度比
mGravitygravity(int gravity)弹窗位置,BottomSheet系列弹窗的位置恒为Gravity.BOTTOM
mBackgroundDrawablebackgroundDrawable(Drawable backgroundDrawable)弹窗window的背景
mDimAmountdimAmount(float dimAmount)弹窗周围的亮度
mAutoDismissTimeautoDismissTime(long autoDismissTime)x秒后自动消失
mCancelablecancelable(boolean cancelable)返回键事件关闭弹窗,默认true,对于PopupWindow无效,调用者自行处理其此事件
mCancelableOutsidecancelableOutside(boolean cancelableOutside)点击外部区域关闭弹窗,默认true
mRadius
mRadiusSideLeft
mRadiusSideTop
mRadiusSideRight
mRadiusSideBottom
radius(int radius)
radiusSideLeft(int radiusSideLeft)
radiusSideTop(int radiusSideTop)
radiusSideRight(int radiusSideRight)
radiusSideBottom(int radiusSideBottom)
圆角
左边圆角
上边圆角
右边圆角
下边圆角

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


总结

XPopUp是一个弹窗处理框架,整合了Android几乎所有的弹窗类型,主要是为了简化弹窗的处理方式,直接链式调用,发布这个初版基本能满足大多数业务场景。接下来自己也会继续完善这个库,将弹窗优先级和全局弹窗功能加进来,当然DialogActivity也可以实现不依赖Activity的全局弹窗,自己一个人的力量有限,XPopUp可能有些功能设计考虑的不是很充分,难免会有些错误,希望大家在使用中能多多提点意见,自己也会努力去改进和完善。

最后欢迎大家start

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-05-14 10:04:13  更:2022-05-14 10:05:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 1:53:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码