2025-02-15

導言
    做android 開發有一段時間瞭,很多時候就是做些重復性的數據綁定,還有就是不夠操作不夠靈活,例如,我在某個界面要新增一個按鈕,就需要發佈一個新版本,就這麼一個按鈕的話其實,可以完全由服務器控制,例如UC,凡客他們要更新首頁,不可能為瞭更新一個首頁特地開發一個新版本,那多傻啊,所以,觀察瞭一下,想出瞭一個可能解決的方案…
1.控制顯示
  如何做到有服務器控制客戶端的顯示呢?
  我們可以在客戶端預留一些可能會用的例如UC的首頁:
image
 
箭頭標志的區域,是會根據不同情況而更新,而我現在就是要做出這樣的效果.
如何控制顯示?
  我們知道,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作為例子:
image
 
在 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手機….
試一下效果:
image
 
這是一個開源的玩意…
  這個項目放在瞭github上,如果有朋友,想試一下可以到以下鏈接下載或者關註,提供一些建議,完善的話會慢慢來…

 

摘自 youxiachai

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *