導言
做android 開發有一段時間了,很多時候就是做些重復性的數據綁定,還有就是不夠操作不夠靈活,例如,我在某個界面要新增一個按鈕,就需要發布一個新版本,就這么一個按鈕的話其實,可以完全由服務器控制,例如UC,凡客他們要更新首頁,不可能為了更新一個首頁特地開發一個新版本,那多傻啊,所以,觀察了一下,想出了一個可能解決的方案…
1.控制顯示
如何做到有服務器控制客戶端的顯示呢?
我們可以在客戶端預留一些可能會用的例如UC的首頁:
箭頭標志的區域,是會根據不同情況而更新,而我現在就是要做出這樣的效果.
如何控制顯示?
我們知道,android 找view是通過一系列ID 值找到相關的UI 那樣,我們可以通過,在服務端,發送我們要修改的id.
1,是直接發送ID值還是發送一個具體路徑?
這點,我毫無猶豫的選擇了發送一個ui的路徑,通過在客戶端把這個URI進行轉義,然后獲得,相關的ID值.代碼
/** * 資源ID 的幾種形式 * res = package:type/entry * 1,res://com.achai@drawable/test_icon * 2,res://drawable/test_icon *(1) 不帶具體包名 *entry = layout/main *(2) 指定包名和類型實體 *com.achai@drawable/icon * @param url * @return */ public static int getResIdFromURL(String url){ URI uri = URI.create(url); String scheme = uri.getScheme(); String type = uri.getHost(); String entry = uri.getPath(); entry = entry.replaceFirst("/", ""); String packageName = uri.getUserInfo(); if(ress == null) initRes(); if(ress == null) return -1; //判斷是否android資源URL if(!scheme.equals("res")) return -1; //1,判斷是否是帶包名的uri,並執行轉換,獲得資源ID if(packageName != null){ return ress.getIdentifier(entry, type, packageName); }else{ return ress.getIdentifier(entry, type, defPackage); } }
思路就如同代碼那樣,這樣,我們的客戶端就能夠解析服務端發送過來要改哪個UI的了!接着就是修改值的事情了,這部分,以后繼續!
2,控制監聽
還是用uc作為例子:
在 UC的應用中心中,有個添加應用,這里就有個問題,我們如何監聽我們新增的應用呢?
x
我翻閱android api的時候發現這么一行話
Tags
Unlike IDs, tags are not used to identify views. Tags are essentially an extra piece of information that can be associated with a view. They are most often used as a convenience to store data related to views in the views themselves rather than by putting them in a separate structure.
看到這里,我覺得就可以在這里做點文章了.
我們可以做一個tag 命令系統,然后,在這些新增應用的tag上打上一個標簽命令,例如,UC就可能在這些應用上的tag 打上一個url 我們點擊的時候,就會跳轉到相關的應用.
根據這個思路敲下如下代碼
public void doViewClicked(View v){ String url = v.getTag().toString().trim(); if(v != null && url != null){ //對view 中tag 進行解析 doExecUrl(v, url); } } protected void doExecUrl(View view, String url) { try{ if(url.indexOf('\n') > 0){ String[] urls = url.split("\n"); for(String u : urls){ execUrl(view, u); } }else{ execUrl(view, url); } }catch(RuntimeException ex){ UserApp.curApp().showMessage("url 解析錯誤"); } } private void execUrl(View view, String u) { URI execUri = URI.create(u); if(execUri == null) return; String prefix = execUri.getScheme(); //執行相關的的命令 if(prefix.equals("cmd")){ execCmd(execUri); }else if(prefix.equals("act")){ execAct(execUri); } } /** * 執行命令操作 * @param u */ private void execCmd(URI u){ String type = u.getHost(); //監控 watch if(type.equals("watch")){ //用於觀察view 中的變量改變情況,晚些在實現 return; } //結束當前view if(type.equals("finish")){ theAct.finish(); return; } //彈出提示 if(type.equals("hint")){ String msg = u.getFragment(); if(msg != null){ UserApp.showMessage(theAct, msg); } return; } //重新讀取 if(type.equals("reload")){ return; } //設置指定id view 的值 if(type.equals("setview")){ return; } //設置顯示某個view if(type.equals("showview")){ return; } }
這樣,我們可以在初始化view的時候,遍歷所有view的元素,有tag命令就設置監聽器!
public void checkView(){ ViewGroup vg = (ViewGroup) findViewById(R.id.line); int count = vg.getChildCount(); for(int i=0; i < count; i ++){ View child = vg.getChildAt(i); String tag = (String) child.getTag(); if(tag != null){ initTagCmd.setViewTagListenr(child); } } }
這樣我們就可以很靈活的操作我們的UI 事件了!
k
可能有人會說效率問題?
效率的影響那是肯定會有的,但是,你想一下,一個view 官方推薦不要超過80個,一般而言也就10來個,遍歷消耗的時間估計就算是htc g1(第一台android手機)那樣的配置的手機都沒問題,更何況是現在4核的android手機….
試一下效果:
這是一個開源的玩意…
這個項目放在了github上,如果有朋友,想試一下可以到以下鏈接下載或者關注,提供一些建議,完善的話會慢慢來…



