前言
- 在實際業務中,我們經常會遇到類似activity在實現具體業務,在回調改變view視圖。也就是我們常說的MVP,或者MVVM或者MVVVM。如果是涉及到的彈窗地方,並且有複雜的業務組合呢?這時候代碼書寫該怎麼辦呢?不知道各位在實際操作中是怎麼樣來做的
- 如果這麼說很抽象的話, 不如來設想一下類似微信紅包業務的彈窗業務。因此筆者採用MVP的思想。封裝了一個彈窗的library。
項目
https://github.com/cxMax/Popup
- 廢話不說先上項目,有興趣的可以看下readme.md,用法和各個類的用途也寫得比較清楚了。
用法
- 再說具體代碼實現的話,先說用法吧。很簡單,使用者只需要關心四個步驟即可。
- 第一步:JavaBean類, 彈窗業務相關的實體類, 也就是服務端返回的json實例對象
- 第二步: 彈窗的view類,即初始化view,以及業務回調改變view的類。繼承AbsPopupProvider類,類似CouponProvider.
Override以下方法:
onCreateView() 彈窗的佈局layout
initView() 初始化彈窗相關的控件
updateView() 數據的綁定
initOperation() 初始化處理具體彈窗(內部控件點擊)業務邏輯類
showPopupView() 顯示的位置,默認在屏幕中央
第三步:彈窗的業務類,繼承AbsPopupOperation類, 類似CouponOperation.
具體的控件點擊交互事件可以在PopupOperation接口中定義或者拓展,PopupOperation.PopupView作爲view交互的回調事件定義。第四步:在需要顯示彈窗的地方調用popup的鏈式調用即可。
Popup.with(this)
.windowHeight(390)
.windowWidth(300)
.data(data)
.background(R.drawable.game_gift_popupwindow_use_background)
.clz(CouponProvider.class)
.apply()
.showPopupView();
代碼
- 項目目錄截圖:
- 相關類說明:
- PopupOptions 彈窗相關的屬性
- GeneratorTool , Generator , DialogGenerator , PopupGenerator 具體dialog and popupwindow初始化的代碼。
- AbsPopupProvider, 彈窗view的init和change,都在這個類
- AbsPopupOperation , 彈窗view的交互邏輯
- Popup , 對外提供的一個鏈式調用 , 調用的參數包含彈窗的一些屬性。
- AnimatorUtil 彈窗交互動畫util類
優缺點
優點:
- 使用這個lib來構建窗體,可以節省代碼成本。(參考使用步驟)
- 解決BadTokenException。 ps:相信異步請求回調觸發彈窗的需求,很多同學都遇到過這個bug吧
解決方案:
1.配合rxlivecycle的調用 , 在當前生命週期結束的時候,會cancle掉此次請求
2.Popup.with(this),的實現參考了glide源代碼, 這次傳遞activity 或者 fragment 作爲context,會在彈窗調用show()方法的時候,判斷當前activity/fragment的生命週期情況 - 增加動畫接口,和彈窗樣式接口.相關屬性可以直接在style中配置調用,是不是很方便~
缺點:
- 在AbsPopupProvider的createView() ; PopupGenerator的create(); DialogGenerator的create(); 代碼還可以更優雅的處理.
- 關於整個popup的鏈式調用設計,我覺得可能存在一點缺陷,以下方法必須調用.但方法調用順序可隨意更改.
作爲優化點, 我在想, 鏈式調用設計可不可劃分爲兩部分,即非必須參數,和必須參數.直白一點就是,以下調用的必要參數,作爲(Object… params)只要調用一次就可以了.類似於glide的transform()的調用
Glide.with(context)
.transform(new XXTransformation()
, new XXTransformation()
, new CenterCrop(context));
最後
- 如果有什麼疑問,或者代碼有什麼更好的建議,歡迎私信或者直接留言。