導言
做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();
//執行相關的的命令 www.aiwalls.com
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上,如果有朋友,想試一下可以到以下鏈接下載或者關註,提供一些建議,完善的話會慢慢來…
摘自 youxiachai