GenjiDialog
基于kotlin的通用dialog
之前我是自己Fork了的一個叫NiceDialog的庫,
但是在這基礎(chǔ)上自己加了很多功能來自用阀圾,但是后來開始用kotlin開發(fā)之后哪廓,
發(fā)現(xiàn)很多東西都能簡化,畢竟kotlin的語法糖不能浪費(fèi)了初烘,所以就有了這個庫涡真,
只要我還在做Android開發(fā),應(yīng)該會一直維護(hù)該庫肾筐。
項目地址:https://github.com/q876625596/GenjiDialogV2
依賴
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
dependencies {
implementation 'com.github.q876625596:GenjiDialogV2:1.1.0'
}
廢話不多說哆料,直接上圖
內(nèi)置大量基礎(chǔ)動畫,基本能滿足基本需求
第一次寫README也不知道該怎么吹吗铐,就直接貼代碼吧
newGenjiDialog {
width = dp2px(100f)
height = dp2px(100f)
}.showOnWindow(supportFragmentManager)
就這么簡單东亦,一個默認(rèn)居中的加載中l(wèi)oadDialog就出來了,如圖:
1唬渗、位置
如果我想讓他顯示在屏幕右上角怎么辦典阵?非常簡單!
newGenjiDialog {
width = dp2px(100f)
height = dp2px(100f)
gravity = DialogGravity.RIGHT_TOP
}.showOnWindow(supportFragmentManager)
DialogGravity這個枚舉中我設(shè)定了9種顯示方式镊逝,左上壮啊,中上,右上撑蒜,左中歹啼,正中,右中座菠,左下狸眼,中下,右下
因此只需要添加一行代碼指定dialog的位置就行了辈灼、效果如圖:
你現(xiàn)在可能要問了份企,你只設(shè)置了9個位置,我需要偏移怎么辦呢,
當(dāng)然巡莹,這時候就需要用到偏移了
newGenjiDialog {
width = dp2px(100f)
height = dp2px(100f)
verticalMargin = dp2px(100f).toFloat()
horizontalMargin = dp2px(100f).toFloat()
gravity = DialogGravity.RIGHT_TOP
}.showOnWindow(supportFragmentManager)
就這樣我就給dialog加上了橫向縱向分別100dp的偏移司志,效果如圖:
關(guān)于這個偏移量甜紫,這里我多說兩句,原本偏移量的取值范圍是在[0-1]骂远,指的是所占屏幕寬高的百分比囚霸,
但是為了方便起見,我這里給大于1的偏移量自動換算成了百分比激才,如果針對個別機(jī)型有誤差的拓型,可以自行換算成[0-1]即可
2、動畫
細(xì)心地你可能發(fā)現(xiàn)了瘸恼,在屏幕右上角顯示的時候是從屏幕邊緣滑出的劣挫,
沒錯,我給DialogGravity的每一個顯示位置都設(shè)定了默認(rèn)的動畫东帅,
當(dāng)沒有指定動畫的時候就會按照默認(rèn)的動畫來顯示压固、
當(dāng)然自定義動畫是肯定要有的
newGenjiDialog {
width = dp2px(100f)
height = dp2px(100f)
animStyle = R.style.ScaleADEnterExitAnimationX50Y50
gravity = DialogGravity.RIGHT_TOP
}.showOnWindow(supportFragmentManager)
這樣就完成了動畫的自定義,當(dāng)然你還可以這樣寫:
dialog.showOnWindow(supportFragmentManager,DialogGravity.RIGHT_TOP,R.style.ScaleADEnterExitAnimationX50Y50)
效果如圖:
內(nèi)置動畫我在style文件中注釋寫了作用靠闭,可以自己去看看
如果想要貼在一個view附近怎么辦帐我?
newGenjiDialog {
width = dp2px(100f)
height = dp2px(100f)
animStyle = R.style.ScaleADEnterExitAnimationX50Y100
gravityAsView = DialogGravity.CENTER_TOP
}.showOnView(supportFragmentManager,showLoading)
需要注意的是這里的gravaty換成了gravityAsView,效果如圖:
同樣你還可以這樣寫:
dialog.showOnWindow(supportFragmentManager,DialogGravity.RIGHT_TOP,R.style.ScaleADEnterExitAnimationX50Y50)
相對view的偏移量 offsetX和offsetY屬性
這兩個屬性建議去DialogOptions中的dialogAsView()方法去查看方法注釋
附加一個稍微特殊點(diǎn)的滑出方式(帶遮罩)
newGenjiDialog { genjiDialog ->
//設(shè)置布局
layoutId = R.layout.slide_view_bottom
//isLazy = true
//設(shè)置橫縱向占滿
isFullHorizontal = true
isFullVerticalOverStatusBar = true
//陰影透明度
dimAmount = 0f
//處理事件/數(shù)據(jù)綁定
convertListenerFun { holder, dialog ->
//設(shè)置點(diǎn)擊realView以外的部分就dismiss
holder.setOnClickListener(R.id.bottomTouchView) {
if (canClick) {
dialog.dismiss()
}
}.setOnClickListener(R.id.topTouchView) {
if (canClick) {
dialog.dismiss()
}
}
}
setOnEnterAnimator { rootView ->
//在此處設(shè)置進(jìn)入動畫
AnimatorSet().apply {
duration = 500L
val realView = rootView.findViewById<View>(R.id.realView)
val touchView = rootView.findViewById<View>(R.id.bottomTouchView)
val topTouchView = rootView.findViewById<View>(R.id.topTouchView)
val maskLayout = rootView.findViewById<View>(R.id.maskLayout)
//給realView的父布局(遮罩布局)設(shè)置距頂部margin
maskLayout?.apply {
layoutParams = (layoutParams as ConstraintLayout.LayoutParams).apply {
topMargin = (slideForBottom.y + slideForBottom.height).toInt()
}
}
play(ObjectAnimator
.ofFloat(realView, "y", -UtilsExtension.dp2px(resources, 200f).toFloat(), 0f))
.with(ObjectAnimator
.ofFloat(touchView, "alpha", 0f, 1f))
.with(ObjectAnimator
.ofFloat(topTouchView, "alpha", 0f, 1f))
}
}
setOnExitAnimator {
//退出動畫
AnimatorSet().apply {
duration = 500L
val realView = it.findViewById<View>(R.id.realView)
val touchView = it.findViewById<View>(R.id.bottomTouchView)
val topTouchView = it.findViewById<View>(R.id.topTouchView)
play(ObjectAnimator
.ofFloat(realView, "y", 0f, -UtilsExtension.dp2px(resources, 200f).toFloat()))
.with(ObjectAnimator
.ofFloat(touchView, "alpha", 1f, 0f))
.with(ObjectAnimator
.ofFloat(topTouchView, "alpha", 1f, 0f))
}
}
}.showOnWindow(supportFragmentManager)
效果圖:
基本的顯示模式都已經(jīng)說了愧膀,接下來就放一個整體可見的參數(shù)表格出來
GenjiDialog中
屬性名/方法名 | 介紹 |
---|---|
rootView | layoutId所對應(yīng)的布局 |
getMyActivity() | 獲取該dialog所在的activity |
setDialogOptions(...) | 設(shè)置dialogOptions |
getDialogOptions() | 獲取dialogOptions |
extendsOptions() | 當(dāng)繼承GenjiDialog時需要重寫該方法拦键,在該方法里面設(shè)置新的dialogOptions |
showOnWindow(...) | 將dialog顯示在屏幕中,有多個重載方法檩淋,具體可見源碼注釋 |
showOnView(...) | 將dialog依附于某個View芬为,有多個重載方法,具體可見源碼注釋 |
DialogOptions
屬性名/方法名 | 介紹 |
---|---|
layoutId | 布局id狼钮,默認(rèn):R.layout.loading_layout |
dialogStyle | dialog的樣式碳柱,一般情況下不用修改捡絮,為了方便某些朋友可能有特殊需求熬芜,所以放出來可供重寫,默認(rèn):DialogFragment.STYLE_NO_TITLE |
dialogThemeFun | dialog的主題福稳,同上涎拉,重寫方法setDialogTheme(fun) |
setStatusBarModeFun | dialog的狀態(tài)欄設(shè)置,同上的圆,重寫方法setStatusMode(fun) |
animStyle | dialog的進(jìn)出動畫鼓拧,用于一般情況,內(nèi)置了很多日常所需動畫越妈,可以到res/values/styles中查看季俩,動畫文件在res/anim中查看,默認(rèn)根據(jù)gravity來判斷 |
setOnEnterAnimator(fun) | dialog的進(jìn)入動畫梅掠,這個動畫是用于一些特殊情況酌住,比如上面的帶遮罩的滑出動畫店归,默認(rèn):null |
exitAnimator(fun) | dialog的退出動畫,同上 (這兩個動畫的示例請看上面帶遮罩滑出動畫的代碼酪我,也可以去源碼查看) |
canClick | 否可以觸發(fā)取消消痛,默認(rèn):true,比如在動畫開始時將此屬性設(shè)置false都哭,防止在動畫進(jìn)行時秩伞,被再次觸發(fā)動畫,當(dāng)使用上面兩種自定義特殊動畫時欺矫,我已經(jīng)默認(rèn)添加了改變這個狀態(tài)值的監(jiān)聽 |
isLazy | 是否懶加載纱新,默認(rèn):false,是否在動畫完成時才執(zhí)行convertListener |
duration | 懶加載的延時穆趴,默認(rèn):0L怒炸,配合isLazy使用,這個值一般設(shè)置為動畫的時長毡代,為了保證動畫流暢 |
dialogStatusBarColor | dialog的statusBar顏色阅羹,默認(rèn):透明,一般來說無需改變 |
width | dialog寬度教寂,默認(rèn):0px |
height | dialog高度捏鱼,默認(rèn):0px |
isFullHorizontal | dialog是否橫向占滿,默認(rèn):false |
isFullVertical | dialog是否縱向占滿酪耕,默認(rèn):false导梆,該縱向占滿并非全屏,縱向占滿會自動扣掉狀態(tài)欄的高度 |
isFullVerticalOverStatusBar | dialog是否縱向占滿迂烁,默認(rèn):false看尼,該縱向占滿全屏不會扣掉狀態(tài)欄高度,是真正的全屏 |
verticalMargin | dialog上下邊距,默認(rèn):0盟步,詳細(xì)注釋請在源碼中查看 |
horizontalMargin | dialog左右邊距藏斩,默認(rèn):0,詳細(xì)注釋請在源碼中查看 |
fullVerticalMargin | dialog在上下占滿時的邊距却盘,默認(rèn):0px |
fullHorizontalMargin | dialog在左右占滿時的邊距狰域,默認(rèn):0px |
dimAmount | dialog背景的陰影的透明度:默認(rèn):0.3f |
gravity | dialog顯示為showOnWindow()時的位置:默認(rèn):DialogGravity.CENTER_CENTER |
gravityAsView | dialog顯示為showOnView()時的位置:默認(rèn):DialogGravity.CENTER_BOTTOM |
dialogViewX | x軸坐標(biāo)值,用于特殊動畫時定位dialog黄橘,默認(rèn):0px |
dialogViewY | y軸坐標(biāo)值兆览,用于特殊動畫時定位dialog,默認(rèn):0px |
offsetX | 當(dāng)dialog依附在view上時x軸的偏移量塞关,默認(rèn):0px |
offsetX | 當(dāng)dialog依附在view上時x軸的偏移量抬探,默認(rèn):0px |
touchCancel | 是否點(diǎn)擊屏幕區(qū)域取消(不包含返回按鈕),默認(rèn):false |
outCancel | 是否點(diǎn)擊外部取消帆赢,默認(rèn):false小压,當(dāng) touchCancel == true時此屬性無效砰左,必須是 touchCancel和該屬性均為false時,那么點(diǎn)擊屏幕區(qū)域和返回按鈕都不能關(guān)閉dialog |
showDismissMap | 顯示與消失的監(jiān)聽map |
onKeyListener | 按鈕監(jiān)聽 |
convertListener | view初始化 |
這里我給出的屬性/方法场航,注釋不詳細(xì)可以到DialogOptions源碼里面查看缠导,那里面注釋很詳細(xì)