一 何爲apkplug自定義樣式切換 java
apkplug主題切換包含兩個層次 網絡
1.通用主題,與系統主題類似 ide
2.自定義控件樣式切換 this
根據上一篇文章講解咱們能夠斷定通用主題有其侷限性,在不少狀況下咱們須要替換的是與咱們應用本事相結合的自定義控件樣式。如QQ聊天掛件 插件
QQ皮膚,QQ聊天泡泡等。針對這種狀況咱們爲apkplug新設計了一套接口,以知足開發者這方面的需求。 設計
二 自定義控件樣式切換 代理
自定義控件樣式,顧名思義是咱們開發者要求的自定義,由於它與開發的應用自己有關,不一樣的應用有不一樣的設計要求和格式。因此不是可提早統必定義的。 code
三 定義自定義控件樣式替換接口 接口
根據apkplug的要求,開發者要替換某些自定義控件的樣式就應該提早定義一套替換接口(模板),主題包能夠根據該模板填充相應的樣式ID傳遞給主應用。不過apkplug並無要求模板的定義格式惟一規定的是該模板必須是一個java interface 以下: 事件
public interface chatstyles { //咱們協定若是 返回值小於0爲未設置狀態 //主題樣式版本,若是主題樣式接口有所改變就利用這來判斷 public int Version(); //聊天界面右側Item 背景樣式 public int chat_right_msg_background(); //聊天界面左側Item 背景樣式 public int chat_left_msg_background(); //聊天界面背景 public int chatbackground(); }
四 將模板導出爲一個jar包提供給主題包使用
五 主題包填充模板並傳遞給主應用
1.主題包外部導入模板 jar包(相似osgi.jar包)
2.填充模板
public class chatstylesImp implements chatstyles{ @Override public int chat_left_msg_background() { return R.drawable.chat_btn_left; } @Override public int chat_right_msg_background() { return R.drawable.chat_btn_right; } @Override public int Version() { return 0; } @Override public int chatbackground() { return R.drawable.menu_background; } }
3.將模板傳遞註冊到apkplug中,以備未來某時被主應用引用
OSGIServiceAgent<ThemeControl> agent=new OSGIServiceAgent<ThemeControl>(mcontext,ThemeControl.class.getName()); //自定義控件樣式切換 agent.getService().addStyles(mcontext, chatstyles.class.getName(), new chatstylesImp()); //通用樣式切換 agent.getService().setTheme(mcontext,mcontext.getBundle(), R.style.AppTheme_Another);
注:此處有一個小點須要注意的是 只有通用樣式切換設置爲該主題包其自定義控件樣式纔會生效
4.主應用在繪製界面時判斷是否與可替換的主題樣式 ?
由於咱們不知道什麼時候可能有主題包會提供主題替換的樣式,因此咱們就假定在UI建立的時候對模板進行判斷,若是有就用模板的樣式ID設置到對應的UI控件上,若是沒有就用默認的。因此主題樣式切換須要刷新Activity
ThemeAgent<chatstyles> ta=new ThemeAgent<chatstyles>(mcontext,chatstyles.class); chatstyles ct=ta.getService(); if(ct!=null){ //表示有主題包提供可替換的主題樣式 }else{ //表示沒有可替換的主題樣式 }自定義UI控件替換樣式代碼示例
chatstyles cs=ThemeChengFactory.getInstance(null).getService(); if(cs!=null){ ViewHolder v= (ViewHolder)convertView.getTag(); if(isComMsg){ if(cs.chat_left_msg_background()!=-1){ v.tvContent.setBackgroundResource(cs.chat_left_msg_background()); } }else{ if(cs.chat_right_msg_background()!=-1){ v.tvContent.setBackgroundResource(cs.chat_right_msg_background()); } } }
5.主應用怎知有主題包提供了一套切換樣式並重繪界面?
樣式是隨時切換的,且能夠經過網絡下主題包動態切換.因此咱們的主應用須要一套機制來判斷合適切換UI樣式。目前apkplug主題切換樣式須要Activity重啓來實現,咱們提供如下接口來監聽主題切換事件並在適當時機重啓刷新Activity
BundleContext context=frame.getSystemBundleContext(); //RegThemeChengeListener 服務代理 OSGIServiceAgent<RegThemeChengeListener> agent=new OSGIServiceAgent<RegThemeChengeListener> (context,RegThemeChengeListener.class.getName()); final RegThemeChengeListener service=agent.getService(); //插件啓動級別爲1(會自啓) 而且不檢查插件版本是否相同都安裝 service.registerOnThemeListener( new OnThemeChengeListener(){ @SuppressLint("NewApi") @Override public void afterChenged( org.osgi.framework.Bundle arg0, int arg1) { //主題切換了刷新界面 MainActivity.this.recreate(); //監聽完註銷該監聽器,由於界面重刷之後會註冊新的 service.unregisterOnThemeListener(this); } @Override public void beforeChenge( org.osgi.framework.Bundle bb, int arg1,org.osgi.framework.Bundle tob, int arg2) { } });