Nebula 容器可支援自訂導覽列,您可以制定導覽列的樣式,例如標題的位置、返回按鈕的樣式等。本文將向您介紹如何在 10.1.68 基準中自訂導覽列。
前提條件
在完整閱讀此指南前,需提前知曉以下四點:
由於小程式和 H5 共用導覽列的實現,在進行自訂導覽列的開發時應將 H5 和小程式使用導覽列的情況都考慮在內,除非確定使用情境不包含小程式或 H5。
自訂導覽列 必須符合容器調用的標準流程,請仔細閱讀本文檔並按照要求進行開發。
小程式導覽列預設使用內建導覽列,如需開啟自訂導覽列,詳情請參考 容器配置。
由於導覽列的顏色可以動態設定,為達到最佳體驗效果,您應當準備 兩套主題配置 並根據不同情境進行切換。
接入步驟
繼承 AbsTitleView 抽象類別並實現自訂導覽列。
實現
H5ViewProvider
,在createTitleView
方法中建立並返回自訂導覽列執行個體。public class H5ViewProviderImpl implements H5ViewProvider { @Override public H5TitleView createTitleView(Context context) { return new NewH5TitleViewImpl(context); } @Override public H5NavMenuView createNavMenu() { return null; } @Override public H5PullHeaderView createPullHeaderView(Context context, ViewGroup viewGroup) { return null; } @Override public H5WebContentView createWebContentView(Context context) { return null; } }
在合適的地方,比如應用啟動時,設定
H5ViewProvider
至容器。MPNebula.setCustomViewProvider(new H5ViewProviderImpl());
如果工程是基於 Portal&Bundle 架構,需額外設定。
H5Utils.setProvider(H5ReplaceResourceProvider.class.getName(), new H5ReplaceResourceProvider() { @Override public String getReplaceResourcesBundleName() { return BuildConfig.BUNDLE_NAME; } });
更多擴充
背景色
resetTitle 一般在前端頁面調用 setTitleColor 的 JSAPI 時被觸發。這種情況下,建議您將導覽列的背景以及其他後續提及組件的色值等顯示元素重設為預設元素。
/**
* 返回導覽列背景顏色值
* @return
*/
public abstract int getBackgroundColor();
/**
* 設定導覽列透明度
* @param alpha
*/
public abstract void setBackgroundAlphaValue(int alpha);
/**
* 設定導覽列背景色,不含 alpha 值
* @param color
*/
public abstract void setBackgroundColor(int color);
/**
* 重設導覽列
*/
public abstract void resetTitle();
標題
副標題當前僅在 H5 情境中支援,如應用不需要副標題,可以不提供副標題實現。
為了使 H5 頁面能夠監聽 點擊標題列事件,導覽列應該在合適的地方調用 invokeTitleClickEvent
方法;監聽 點擊副標題列事件,則調用 invokeSubTitleClickEvent
方法。
/**
* 返回主標題文本
* @return
*/
public abstract String getTitle();
/**
* 設定主標題文本
* @param title
*/
public abstract void setTitle(String title);
/**
* 設定副標題文本
* @param subTitle
*/
public abstract void setSubTitle(String subTitle);
/**
* 返回主標題視圖
* @return
*/
public abstract TextView getMainTitleView();
/**
* 返回副標題視圖
* @return
*/
public abstract TextView getSubTitleView();
左側控制區
/**
* 設定關閉按鈕可見度
* @param visible
*/
public abstract void showCloseButton(boolean visible);
/**
* 設定返回按鈕可見度
* @param visible
*/
public abstract void showBackButton(boolean visible);
/**
* 設定去首頁按鈕可見度
* @param visible
*/
public abstract void showBackHome(boolean visible);
/**
* 設定標題列載入提示符可見度
* @param visible
*/
public abstract void showTitleLoading(boolean visible);
關閉按鈕
如上圖紅框地區中所顯示,關閉按鈕僅出現在 H5 情境中,當線上頁面的歷史(即瀏覽器歷史頁面數)大於 1 時,容器會調用 showCloseButton
方法來控制其可見度。此按鈕被點擊時必須調用 invokePageCloseEvent
方法以符合容器行為規範。
返回按鈕
上圖紅框地區中的返回按鈕是 必須 要在自訂導覽列上實現的控制項,容器調用 showBackButton
方法控制其可見度。響應返回按鈕點擊時,開發人員必須調用 invokePageBackEvent
方法以符合容器行為規範。
去首頁按鈕
去首頁按鈕僅在小程式情境下使用,當跳轉小程式的非首頁頁面時,容器會調用 showBackHome
方法控制其可見度。響應按鈕點擊事件時,開發人員必須調用 invokeHomeClickEvent
方法以符合容器行為規範。
載入提示符
當 H5 頁面或者小程式調用導覽列載入動畫 API 時,容器會調用 showTitleLoading
方法控制其可見度。
右側控制區
右側控制區,也可稱為 OptionMenu
控制區,主要用於提供更多操作給使用者。
H5 容器:
小程式:
由上圖可見,開發人員需要為 OptionMenu
控制區預留兩個視圖地區,容器操作時會按照索引來操作這兩塊地區,從右至左,從 0 開始。
public abstract void showOptionMenu(boolean visible);
public abstract View getOptionMenuContainer(int index);
public abstract void setOptionMenu(boolean reset, boolean override, boolean isTinyApp, List<MenuData> menus);
容器通過調用 showOptionMenu
方法來控制 OptionMenu
地區可見度,在某些情況也需要擷取該地區的視圖進行操作,開發人員需要正確實現 getOptionMenuContainer
方法。
實現 setOptionMenu
方法,請參考 設定右上方按鈕 API 入參進行合理的實現。icontype
為內建按鈕樣式,僅在 H5 情境中可用,如果接入情境中不會用到則可忽略,否則需要為不同類型配置相應的按鈕。redDot
與 icontype
類似,可以選擇性接入。
為了使 H5 頁面或小程式監聽右上方按鈕點擊事件,開發人員需要調用 invokeOptionClickEvent
方法。
在小程式情境下:
setOptionMenu
方法的isTinyApp
參數值必定為true
,以此區分 H5 和小程式情境。必須從 最右側倒數第二個 按鈕開始設定按鈕。
小程式右上方控制區
當處於小程式情境時,最右側地區需要特殊實現,步驟如下:
繼承
AbsTinyOptionMenuView
抽象類別實現自訂控制區。在合適的地方,比如應用啟動時,設定
TinyOptionMenuViewProvider
至容器。H5Utils.setProvider(TinyOptionMenuViewProvider.class.getName(), new TinyOptionMenuViewProvider() { @Override public AbsTinyOptionMenuView createView(Context context) { return new TinyOptionMenuView(context); } });
按照容器規範要求,開發人員必須實現和配置 更多 和 關閉 按鈕視圖。
public abstract void setOptionMenuOnClickListener(View.OnClickListener listener);
public abstract void setCloseButtonOnClickListener(View.OnClickListener listener);
public abstract void setCloseButtonOnLongClickListener(View.OnLongClickListener listener);
public abstract void onStateChanged(TinyAppActionState currentState);
public abstract View getView();
容器會調用上方代碼中的前三個方法來設定合理的響應回調,開發人員必須讓指定的視圖設定該響應回調。
onStateChanged
方法在定位、藍芽情境中會被調用,舉例來說,當小程式正在使用定位服務的時,容器會調用此方法,開發人員可作出響應,下面是樣式效果。
簡單範例程式碼:
public class TinyOptionMenuView extends AbsTinyOptionMenuView {
private View container;
private ImageView ivMore;
private View ivClose;
private Context context;
public TinyOptionMenuView(Context context) {
this.context = context;
ViewGroup parent = null;
if (context instanceof Activity) {
parent = (ViewGroup) ((Activity) context).findViewById(android.R.id.content);
}
container = LayoutInflater.from(context).inflate(R.layout.layout_tiny_right, parent, false);
ivClose = container.findViewById(R.id.close);
ivMore = (ImageView) container.findViewById(R.id.more);
}
@Override
public View getView() {
return container;
}
@Override
public void setOptionMenuOnClickListener(View.OnClickListener onClickListener) {
ivMore.setOnClickListener(onClickListener);
}
@Override
public void setCloseButtonOnClickListener(View.OnClickListener onClickListener) {
ivClose.setOnClickListener(onClickListener);
}
@Override
public void setCloseButtonOnLongClickListener(View.OnLongClickListener onLongClickListener) {
ivClose.setOnLongClickListener(onLongClickListener);
}
@Override
public void onStateChanged(TinyAppActionState state) {
if (state == null) {
ivMore.setImageDrawable(context.getResources().getDrawable(R.drawable.icon_more));
} else if (state.getAction().equals(TinyAppActionState.ACTION_LOCATION)) {
ivMore.setImageDrawable(context.getResources().getDrawable(R.drawable.icon_miniprogram_location));
}
}
}
主題變更
不同的小程式或 H5 應用可能會設定不同的導覽列背景色,考慮到使用者體驗,在導覽列背景色發生變化的時候,也需要對導覽列上的其他元素進行調整,比如右上方控制區。
在導覽列的擴充上,右上方控制區和導覽列分別為不同的組件,所以我們提供介面來方便開發人員能夠讓右上方控制區能夠及時響應導覽列的變化。
AbsTinyOptionMenuView
提供onTitleChanged
方法供 override 來響應導覽列變化。當此方法被調用時,可通過傳入H5TitleView 對象來擷取導覽列的資訊,如背景色。也可以使用AbsTinyOptionMenuView
提供的getTitleBar
方法直接擷取導覽列對象。另外,您可以將 H5TitleView 轉換成自己實現的導覽列對象,因為AbsTitleView
實現了H5TitleView
介面類,這樣能夠獲得更多的導覽列資訊。protected void onTitleChange(H5TitleView title)
您需要主動調用
AbsTitleView
提供的notifyTitleBarChanged
方法觸發onTitleChange
被調用,比如在對導覽列對象設定背景色時。舉例說明:package com.mpaas.demo.nebula; public class NewH5TitleViewImpl extends AbsTitleView { @Override public void setBackgroundAlphaValue(int i) { content.getContentBgView().setAlpha(i); notifyTitleBarChanged(); } @Override public void setBackgroundColor(int i) { content.getContentBgView().setColor(i); notifyTitleBarChanged(); } @Override public void resetTitle() { content.getContentBgView().setColor(context.getResources().getColor(R.color.h5_default_titlebar_color)); notifyTitleBarChanged(); } }
上述範例程式碼調用
notifyTitleBarChange
方法時,AbsTinyOptionMenuView
的子類對象可能並沒有初始化完畢,因此建議覆寫setH5Page
方法,擷取導覽列資訊並判定當前主題,樣本如下:public class TinyOptionMenuView extends AbsTinyOptionMenuView { @Override public void setH5Page(H5Page h5Page) { super.setH5Page(h5Page); // title becomes available from here. if (getTitleBar().getBackgroundColor() == -1) { bgView.setBackgroundColor(Color.RED); } } }