本文作者為騰訊Bugly特約撰稿人:騰訊自選股客戶端工程師 王金波
問題描述
做過Android開發(fā)的人都遇到過這樣的問題:隨著需求的變化,某些入口界面通常會出現(xiàn)UI的增加、減少、內容變化以及跳轉界面變化等問題。每次發(fā)生變化都要手動修改代碼,而入口界面通常具有未讀信息提醒這樣的“小紅點”邏輯;一旦UI變化,“小紅點”邏輯也要重新計算。如果不同的RD來維護這些代碼,耦合性非常高,出錯概率也很大。本文以自選股的個人頁卡為例(界面如下圖所示),給出了一套方案來解決動態(tài)更新UI的問題以及更好的解決未讀提醒的邏輯。
舊的方案(Phase out)
對于UI動態(tài)變化的問題,通常結合遠程控制來解決。
以上圖的“資產管理”為例,舊的解決方案會在XML寫死全部的item,如:“港股交易”、“基金交易”和“精品理財”這三個item。然后根據(jù)后臺傳遞過來的JSON解析出需要隱藏哪些item。點擊不同的item會跳轉到不同的activity(如下圖所示),這部分跳轉操作也是寫死在代碼中的。
這解決了一部分問題,但是如果需求新增了item,比如新增了“滬深交易”、“美股交易”,那就需要改動現(xiàn)有代碼了。
對于未讀指示(小紅點)功能,它的作用是,有未讀信息來了,需要在UI上面顯示一個小紅點提醒用戶。比如下圖的股友動態(tài)的頭像提醒,資產管理的“NEW”提醒,系統(tǒng)設置的新版本提醒等。
舊的方案是定義了一個int型(32位),用它的每一位代表一個UI上的item。比如好友動態(tài)是第1位,未讀提醒是第2位... “小紅點”思想是哪個item有未讀信息,則該int型對應的那一位就置1,否則為0。一旦某個item有未讀提醒的改變,則將這個int型對應的位改變,異步寫入SharedPreference中,同時利用觀察者模式通知UI做更新,如下圖所示:
上述做法總體來說大的缺陷就是沒有做到“開放-封閉”原則。面對擴展的時候,即添加一個item則不得不修改現(xiàn)有代碼,需要在該int型中添加一位標志位,觀察者模式也要注冊新item。所以下面我會介紹另一種方案可以更好的解決該問題。
新的解決方法
數(shù)據(jù)抽象
首先進行數(shù)據(jù)的抽象,并將UI進行分組,如下圖所示:
按照組合模式,將數(shù)據(jù)以樹形結構組織起來,表現(xiàn)“整體/部分”層次結構,如下圖所示。這樣做的好處是,可以以一致的方式來處理個別對象以及對象組合。藍色的表示節(jié)點,而綠色的表示葉節(jié)點。
組合模式的類圖,如下所示:
對UI進行的數(shù)據(jù)抽象。無論是ListItem列表項,還是GridView Item的項,都采用了PersonalItem對象來表示,如下所示:
對于PersonalItem來說,有些沒有意義的方法就不實現(xiàn),如add()、remove()、getChild()等,調用它們會拋出UnsupportedOperationException()異常。
完美解決未讀提醒(小紅點)的問題
關于計算小紅點,PersonalGroup類利用組合+迭代器的模式,代碼如下:
這里使用了迭代器,用它遍歷所有PersonalComponent組件。遍歷過程中可能遇到PersonalItem也可能遇到PersonalGroup。由于它們都是PersonalComponent,且實現(xiàn)了getUnreadIndicator()方法,那我們只需調用getUnreadIndicator()即可。
如上圖所示,PersonalGroup中加載的是PersonalComponent,可能是PersonalItem也可能是PersonalGroup。組合模式的優(yōu)點就是無視具體類型 -- 獲取出來的都是PersonalComponent,然后利用多態(tài),調用具體類的getUnredIndicatorCount()方法。如果是PersonalGroup,則繼續(xù)調用它的這個方法(與此方法一樣,會開始另一個遍歷);如果為PersonalItem,則說明遍歷到了樹形結構的末端(即葉節(jié)點),則進行如下處理:
如果getUnreadIndicator為true,則表示該PersonalComponent需要顯示小紅點。因此,利用上述組合+迭代方式,運用遞歸在根節(jié)點處進行一次調用即可。如下圖所示,當計算出葉節(jié)點“A股大賽”有未讀提醒,則它上級的groups也有未讀提醒,一直統(tǒng)計到根節(jié)點。
getUnredIndicatorCount()是每一個item自己來決定自己是否需要展示小紅點的方法。這就是將局部與整體解耦了。整體上面,需要計算小紅點,至于如何計算則委托給具體類來實現(xiàn)。即面向對象中的將 "做什么" 與 "怎么做"分開。RD可以從中解放出來,不必關注整體實現(xiàn),只需關注自己的實現(xiàn)即可。比如,需要在“資產管理”中添加“美股交易”,RD只需添加“美股交易”的內容即可。下一節(jié)會說明,這部分內容也由遠程控制來代勞了,遠程控制傳遞過來的Date與本地存儲的Date比較,如果是新的Date值,則證明這個item為“NEW”,則對應的小紅點需要顯示。
遠程控制動態(tài)更新UI
當遠程控制發(fā)生變化時(5分鐘主動發(fā)一次請求),通過解析遠程控制接口返回的JSON串,生成PersonalItem對象的列表。其中每一項對應UI上面的一個item。需要注意的是,這里還包含了一個URL,它是點擊UI控件跳轉的URL。以“資產管理”為例,它包含“滬深交易”、“基金交易”等子項。當點擊任意一個子項的時候啟動的是同一個Activity - WebviewActivity,它包含一個WebView控件。因為每個子項的跳轉URL不一樣,所以這個WebView load了不同的URL,即完成了跳轉不同界面的問題。 然后按照上面描述的樹形結構,把PersonalItem放到Groups中。如下圖所示:
Model存儲了待顯示的數(shù)據(jù)結構。這份數(shù)據(jù)通過Parser的解析生成UI的內容。過程如下圖所示:
Parser模塊是一個遞歸函數(shù),遞歸的對Model進行解析。并將解析出來的List Item、Grid Group、GridView Item加載各自的XML文件,在程序中動態(tài)的添加UI組件。其中onClick事件是在定義PersonalItem的時候已經寫好了回調。例如,“資產管理”屬于Grid Group,其子項“滬深交易”、“基金交易”等屬于GridView Item。在上述“Build PersonalItem Objects”步驟中,已經定義了onClick方法,調用onClick方法跳轉至WebViewActivity,這個Activity會加載不同GridView Item的URL,從而實現(xiàn)點擊不同item跳轉不同頁面的目的。
Note:
對于ListItem元素,即上圖的列表項(不是GridView元素),并沒有實現(xiàn)遠程更新的策略。因為它們跳轉的邏輯是跳轉到各自的Activity,是固定不變的;并且它們的文字描述、圖標、是否隱藏均不需要后臺來控制更新。故實際項目中,只對GridView內容作了遠程控制動態(tài)更新UI機制的處理。
另外,在通過遠程控制動態(tài)更新UI的過程中也遇到了一些坑,比如遠程控制更新的時刻,恰好用戶退出App,此時系統(tǒng)剛好銷毀Activity。那么在執(zhí)行到上述Parser模塊的inflateUI的時候就需要判斷當前上下文是否為空,如果為空則直接退出。
結論與數(shù)據(jù)
本文通過將UI數(shù)據(jù)進行抽象,利用組合模式進行數(shù)據(jù)的構建,利用遞歸的方式將數(shù)據(jù)映射為UI,同時處理了點擊事件。數(shù)據(jù)源則可以通過遠程控制動態(tài)的更新,RD從中解放。另外,組合+迭代器的方式完美的解決了小紅點的問題,遵循了“開放-封閉”原則,將“做什么”與“怎么做”分開。
另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。
文章標題:Android:結合遠程控制來解決安卓問題-創(chuàng)新互聯(lián)
標題網址:http://m.2m8n56k.cn/article30/dppjso.html
成都網站建設公司_創(chuàng)新互聯(lián),為您提供云服務器、外貿建站、靜態(tài)網站、網頁設計公司、微信小程序、全網營銷推廣
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:[email protected]。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內容