全部產品
Search
文件中心

Mobile Platform as a Service:自訂導覽列(10.1.68)

更新時間:Jul 13, 2024

Nebula 容器可支援自訂導覽列,您可以制定導覽列的樣式,例如標題的位置、返回按鈕的樣式等。本文將向您介紹如何在 10.1.68 基準中自訂導覽列。

前提條件

在完整閱讀此指南前,需提前知曉以下四點:

  • 由於小程式和 H5 共用導覽列的實現,在進行自訂導覽列的開發時應將 H5 和小程式使用導覽列的情況都考慮在內,除非確定使用情境不包含小程式或 H5。

  • 自訂導覽列 必須符合容器調用的標準流程,請仔細閱讀本文檔並按照要求進行開發。

  • 小程式導覽列預設使用內建導覽列,如需開啟自訂導覽列,詳情請參考 容器配置

  • 由於導覽列的顏色可以動態設定,為達到最佳體驗效果,您應當準備 兩套主題配置 並根據不同情境進行切換。

接入步驟

  1. 繼承 AbsTitleView 抽象類別並實現自訂導覽列。

  2. 實現 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;
         }
     }
  3. 在合適的地方,比如應用啟動時,設定 H5ViewProvider 至容器。

     MPNebula.setCustomViewProvider(new H5ViewProviderImpl());
  4. 如果工程是基於 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 情境中可用,如果接入情境中不會用到則可忽略,否則需要為不同類型配置相應的按鈕。redDoticontype 類似,可以選擇性接入。

為了使 H5 頁面或小程式監聽右上方按鈕點擊事件,開發人員需要調用 invokeOptionClickEvent 方法。

重要

在小程式情境下:

  • setOptionMenu 方法的 isTinyApp 參數值必定為 true,以此區分 H5 和小程式情境。

  • 必須從 最右側倒數第二個 按鈕開始設定按鈕。

小程式右上方控制區

當處於小程式情境時,最右側地區需要特殊實現,步驟如下:

  1. 繼承 AbsTinyOptionMenuView 抽象類別實現自訂控制區。

  2. 在合適的地方,比如應用啟動時,設定 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);
              }
          }
      }