開箱即用-Android設(shè)計模式實戰(zhàn)-攔截彈窗展示

Android中多個彈窗的排隊展示

在實際的開發(fā)中哥力,我們會遇到多個彈窗的問題喊衫,又不能一次全部彈出治拿,所以我們的代碼就是 if else if else 循環(huán)嵌套逃糟。

例如我們在工作詳情中申請一個工作析既,首先我們就要走一個校驗接口躬贡,然后接口會告訴需要判斷的對象。如下判斷邏輯:

  1. 首先需要先判斷是否是新用戶眼坏,如果是新用戶需要去參加線上培訓(xùn)(跳轉(zhuǎn)頁面)
  2. 判斷用戶是否完善了個人信息拂玻,如果沒有需要去完善個人信息 (跳轉(zhuǎn)頁面)
  3. 判斷個人用工狀態(tài)是否是Approve,如果個人狀態(tài)不對需要聯(lián)系管理員 (撥打電話)
  4. 判斷當(dāng)前用戶是否填寫了每日新冠報告宰译,如果沒有需要填寫新冠表單(跳轉(zhuǎn)瀏覽器)
  5. 判斷當(dāng)前申請的工作是否需要押金檐蚜,如果要押金彈框提示(彈框)
  6. 如果需要押金,你的錢包又恰好有錢沿侈,會提示是否把錢包的錢充值到押金(彈框)
  7. 如果改工作需要人臉信息闯第,需要你采集人臉 (跳轉(zhuǎn)頁面)
  8. 如果是非直營的工作,會提示你非自營工作 (彈窗)
  9. 如果該工作需要what's app 會彈窗提示你輸入賬號 (彈框)
  10. 如果該工作是銀行卡結(jié)算缀拭,你又沒有銀行卡信息咳短,需要填寫銀行卡(新頁面)

...

真實業(yè)務(wù)肯定不止10個條件了肃廓,這里就先寫10個吧。來诲泌,鍵盤給你盲赊,你來寫if else 。你寫完了敷扫? 中間第5個后面再加一個判斷 如果你沒有填寫技能 去新頁面填寫你的技能哀蘑! 這么多if else 中你真的改的動嗎?

什么葵第?你業(yè)務(wù)中就是這么寫的绘迁?你改的動?

就喜歡這種樸實無華的程序員卒密,但是呢相信我缀台,真的非常簡單。畢竟偷懶才是程序員的第一生產(chǎn)力哮奇,所有的設(shè)計模式膛腐,框架,封裝什么的鼎俘,都是為了偷懶哲身,讓我們更輕松一點。來吧贸伐,看看我的實現(xiàn)勘天!

一、攔截器模式的定義

真正的實現(xiàn): 定義攔截器接口

interface Interceptor {
    fun intercept(chain: InterceptChain)
}

定義一個攔截器的基類

abstract class BaseInterceptImpl : Interceptor {

    protected var mChain: InterceptChain? = null

    @CallSuper
    override fun intercept(chain: InterceptChain) {
        mChain = chain
    }

}

具體的邏輯都在攔截鏈管理類中

class InterceptChain private constructor(
    // 彈窗的時候可能需要Activity/Fragment環(huán)境捉邢。
    val activity: FragmentActivity? = null,
    val fragment: Fragment? = null,
    private var interceptors: MutableList<Interceptor>?
) {
    companion object {

        @JvmStatic
        fun create(count: Int = 0): Builder {
            return Builder(count)
        }
    }

    private var index: Int = 0

    // 執(zhí)行攔截器脯丝。
    fun process() {
        interceptors ?: return
        when (index) {
            in interceptors!!.indices -> {
                val interceptor = interceptors!![index]
                index++
                interceptor.intercept(this)
            }

            interceptors!!.size -> {
                clearAllInterceptors()
            }
        }
    }

    private fun clearAllInterceptors() {
        interceptors?.clear()
        interceptors = null
    }

    // 構(gòu)建者模式。
    open class Builder(private val count: Int = 0) {
        private val interceptors by lazy(LazyThreadSafetyMode.NONE) {
            ArrayList<Interceptor>(count)
        }
        private var activity: FragmentActivity? = null
        private var fragment: Fragment? = null

        // 添加一個攔截器伏伐。
        fun addInterceptor(interceptor: Interceptor): Builder {
            if (!interceptors.contains(interceptor)) {
                interceptors.add(interceptor)
            }
            return this
        }

        // 關(guān)聯(lián)Fragment宠进。
        fun attach(fragment: Fragment): Builder {
            this.fragment = fragment
            return this
        }

        // 關(guān)聯(lián)Activity。
        fun attach(activity: FragmentActivity): Builder {
            this.activity = activity
            return this
        }


        fun build(): InterceptChain {
            return InterceptChain(activity, fragment, interceptors)
        }
    }
}

二秘案、攔截器模式的使用

三個簡單的文件就定義了一個攔截器鏈砰苍,我們看看上面的需求我們?nèi)绾螌崿F(xiàn)

具體到工作申請判斷類

public class JobInterceptBean {

    public boolean isNewMember;
    public boolean isFillInfo;
    public boolean isMemberApprove;
    public boolean isNOCVUpload;
    public boolean isNeedDepost;
    public boolean isNeedFace;
    public boolean isUnderCompany;
    public boolean isNeedWhatApp;
    public boolean isNeedBankInfo;
    public boolean isNeedSkill;

    ...
}

具體的攔截器一潦匈,新用戶的攔截阱高。這里直接暴力的跳轉(zhuǎn)頁面

class InterceptNewMember(private val bean: JobInterceptBean) : BaseInterceptImpl() {

    override fun intercept(chain: InterceptChain) {
        super.intercept(chain)

        if (bean.isNewMember) {
            //攔截
            //可以不彈窗,直接就暴力跳轉(zhuǎn)新頁面
            Demo5Activity.startInstance()
        } else {
            //放行- 轉(zhuǎn)交給下一個攔截器
            chain.process()
        }
    }


    //已經(jīng)完成了培訓(xùn)-放行
    fun resetNewMember() {
        mChain?.process()
    }

}

完善信息的攔截茬缩,這里使用彈窗判斷

class InterceptFillInfo(private val bean: JobInterceptBean) : BaseInterceptImpl() {

    override fun intercept(chain: InterceptChain) {
        super.intercept(chain)

        if (!bean.isFillInfo) {
            //攔截
            //跳轉(zhuǎn)新頁面
            showDialogTips(chain)
        } else {
            //放行- 轉(zhuǎn)交給下一個攔截器
            chain.process()
        }
    }

    private fun showDialogTips(chain: InterceptChain) {
        FangIOSDialog(chain.activity).apply {
            setTitle("完善信息")
            setMessage("你沒有完善信息赤惊,你要去完善信息")
            setNegativeButton("跳過"){
                dismiss()
                chain.process()
            }
            setPositiveButton("去完善"){
                Demo5Activity.startInstance()
            }
            show()
        }
    }

}

用戶狀態(tài)使用彈窗判斷

class InterceptMemberApprove(private val bean: JobInterceptBean) : BaseInterceptImpl() {

    override fun intercept(chain: InterceptChain) {
        super.intercept(chain)

        if (!bean.isMemberApprove) {
            //攔截
            showDialogTips(chain)
        } else {
            //放行- 轉(zhuǎn)交給下一個攔截器
            chain.process()
        }
    }

    private fun showDialogTips(chain: InterceptChain) {
        FangIOSDialog(chain.activity).apply {
            setTitle("狀態(tài)不對")
            setMessage("你用戶狀態(tài)不對,聯(lián)系管理員嗎凰锡?")
            setNegativeButton("跳過") {
                dismiss()
                chain.process()
            }
            setPositiveButton("聯(lián)系") {
                dismiss()
                toast("去撥打電話未舟,當(dāng)你狀態(tài)對了才能繼續(xù)")
            }
            show()
        }
    }

}

技能的攔截-使用彈窗判斷

class InterceptSkill(private val bean: JobInterceptBean) : BaseInterceptImpl() {

    override fun intercept(chain: InterceptChain) {
        super.intercept(chain)

        if (bean.isNeedSkill) {
            //攔截
            //跳轉(zhuǎn)新頁面
            showDialogTips(chain)
        } else {
            //放行- 轉(zhuǎn)交給下一個攔截器
            chain.process()
        }
    }

    private fun showDialogTips(chain: InterceptChain) {
        FangIOSDialog(chain.activity).apply {
            setTitle("你沒有填寫技能")
            setMessage("你要去填寫技能嗎圈暗?")
            setNegativeButton("跳過") {
                dismiss()
                chain.process()
            }
            setPositiveButton("去填寫") {
                Demo5Activity.startInstance()
            }
            show()
        }
    }

}

內(nèi)部可以使用 Dialog 或者 PopupWindow 或者第三方的彈窗庫,都是可以的裕膀。具體的可以自行實現(xiàn)员串。下面看看如何使用

    lateinit var newMemberIntercept: InterceptNewMember

        fun navIntercept() {

            //模擬網(wǎng)絡(luò)請求
            LoadingDialogManager.get().showLoading(this@Demo4Activity)
            CommUtils.getHandler().postDelayed({
                LoadingDialogManager.get().dismissLoading()

                val bean = JobInterceptBean(true, false, false, false, true, true, true, true, true, true)

                createIntercept(bean)
            }, 1500)


        }

        //創(chuàng)建攔截彈窗
        private fun createIntercept(bean: JobInterceptBean) {
            newMemberIntercept = InterceptNewMember(bean)

            val chain = InterceptChain.create(4)
                .attach(this@Demo4Activity)
                .addInterceptor(newMemberIntercept)
                .addInterceptor(InterceptFillInfo(bean))
                .addInterceptor(InterceptMemberApprove(bean))
                .addInterceptor(InterceptSkill(bean))
                .build()

            //開始執(zhí)行
            chain.process()

        }

我們把 NewMemberIntercept 單獨提取出來作為成員變量是為了接受到完成培訓(xùn)的通知,對它做放行操作昼扛。


    override fun startObserve() {
        LiveEventBus.get("newMember",Boolean::class.java).observe(this){
            //調(diào)用內(nèi)部放行的方法
            newMemberIntercept.resetNewMember()
        }
    }


看看效果寸齐,NewMemberIntercept 放行與不放行的區(qū)別

可以看到我們的第二個攔截器 InterceptFillInfo 它內(nèi)部就沒有定義放行的方法,如果一旦跳轉(zhuǎn)到新頁面抄谐,但是沒有接收通知去放行的話就會卡在這里渺鹦。

效果:

總結(jié)

這樣就完成了一個攔截器鏈,我們可以自由的定義彈窗蛹含,打電話毅厚,跳轉(zhuǎn)頁面,跳轉(zhuǎn)瀏覽器等自定義的功能浦箱。

我們的業(yè)務(wù)場景是調(diào)用接口獲取到全部的校驗數(shù)據(jù)吸耿,然后再創(chuàng)建 Chain 。當(dāng)然我們也可以先創(chuàng)建 Chain 酷窥。然后把每一個攔截器都設(shè)置為成員變量珍语,每一個攔截器可以調(diào)用不同的接口做校驗,當(dāng)數(shù)據(jù)返回的時候設(shè)置給攔截器暴露的方法竖幔,內(nèi)部再判斷數(shù)據(jù)類型板乙,是否需要放行。

可以說這是一種非常靈活的攔截器鏈拳氢,內(nèi)部使用了責(zé)任鏈模式募逞,單例模式,建造者模式馋评,工廠模式等放接。如果大家有需要可以使用起來长赞。

具體的源碼在此牲证。如有錯漏還請指出,如果有更好的方法也歡迎討論栓霜。

如果覺得不錯還請點贊支持哦蜕青!

到此完結(jié)苟蹈!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市右核,隨后出現(xiàn)的幾起案子慧脱,更是在濱河造成了極大的恐慌,老刑警劉巖贺喝,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件菱鸥,死亡現(xiàn)場離奇詭異宗兼,居然都是意外死亡,警方通過查閱死者的電腦和手機氮采,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門殷绍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鹊漠,你說我怎么就攤上這事篡帕。” “怎么了贸呢?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵镰烧,是天一觀的道長。 經(jīng)常有香客問我楞陷,道長怔鳖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任固蛾,我火速辦了婚禮结执,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘艾凯。我一直安慰自己献幔,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布趾诗。 她就那樣靜靜地躺著蜡感,像睡著了一般。 火紅的嫁衣襯著肌膚如雪恃泪。 梳的紋絲不亂的頭發(fā)上郑兴,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機與錄音贝乎,去河邊找鬼情连。 笑死,一個胖子當(dāng)著我的面吹牛览效,可吹牛的內(nèi)容都是我干的却舀。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼锤灿,長吁一口氣:“原來是場噩夢啊……” “哼挽拔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起衡招,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤篱昔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后始腾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體州刽,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年浪箭,在試婚紗的時候發(fā)現(xiàn)自己被綠了穗椅。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡奶栖,死狀恐怖匹表,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情宣鄙,我是刑警寧澤袍镀,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站冻晤,受9級特大地震影響苇羡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鼻弧,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一设江、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧攘轩,春花似錦叉存、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至笨篷,卻和暖如春甫菠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背冕屯。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工寂诱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人安聘。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓痰洒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親浴韭。 傳聞我的和親對象是個殘疾皇子丘喻,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345