Customize the navigation bar (10.1.68)

更新时间:
复制 MD 格式

The Nebula container lets you customize the navigation bar's appearance, such as the title position and the style of the back button. This topic describes how to customize the navigation bar in baseline 10.1.68.

Prerequisites

Before you begin, note the following:

  • Mini Programs and H5 pages share the same navigation bar implementation. Therefore, when you develop a custom navigation bar, consider the usage scenarios for both H5 pages and Mini Programs, unless you are certain that your use case excludes one of them.

  • Your custom navigation bar must follow the standard container invocation flow. Read this document carefully and develop your navigation bar accordingly.

  • Mini Programs use the built-in navigation bar by default. To enable a custom navigation bar, see Container configuration.

  • Because the navigation bar color can be set dynamically, you must prepare two theme configurations and switch between them based on the scenario to ensure an optimal user experience.

Integration steps

  1. Inherit the AbsTitleView abstract class to implement your custom navigation bar.

  2. Implement H5ViewProvider and then create and return an instance of your custom navigation bar in the createTitleView method.

     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. At an appropriate time, such as during app startup, register your H5ViewProvider with the container.

     MPNebula.setCustomViewProvider(new H5ViewProviderImpl());
  4. If your project uses the Portal&Bundle architecture, additional setup is required.

     H5Utils.setProvider(H5ReplaceResourceProvider.class.getName(), new H5ReplaceResourceProvider() {
         @Override
         public String getReplaceResourcesBundleName() {
             return BuildConfig.BUNDLE_NAME;
         }
     });

Additional extensions

Background color

The `resetTitle` method is typically triggered when a frontend page calls the `setTitleColor` JSAPI. When this occurs, you must reset the navigation bar background and other visual elements to their default values.

    /**
     * Returns the navigation bar background color.
     * @return
     */
    public abstract int getBackgroundColor();

    /**
     * Sets the navigation bar transparency.
     * @param alpha
     */
    public abstract void setBackgroundAlphaValue(int alpha);

    /**
     * Sets the navigation bar background color without alpha.
     * @param color
     */
    public abstract void setBackgroundColor(int color);

    /**
     * Resets the navigation bar.
     */
    public abstract void resetTitle();

Title

Subtitles are supported only in H5 scenarios. If your application does not require subtitles, you can omit the subtitle implementation.

To allow H5 pages to listen for title bar click events, call the invokeTitleClickEvent method at the appropriate place in your navigation bar. To listen for subtitle bar click events, call the invokeSubTitleClickEvent method.

    /**
     * Returns the main title text.
     * @return
     */
    public abstract String getTitle();

    /**
     * Sets the main title text.
     * @param title
     */
    public abstract void setTitle(String title);

    /**
     * Sets the subtitle text.
     * @param subTitle
     */
    public abstract void setSubTitle(String subTitle);

    /**
     * Returns the main title view.
     * @return
     */
    public abstract TextView getMainTitleView();

    /**
     * Returns the subtitle view.
     * @return
     */
    public abstract TextView getSubTitleView();

Left control area

    /**
     * Sets the visibility of the Close button.
     * @param visible
     */
    public abstract void showCloseButton(boolean visible);

    /**
     * Sets the visibility of the Back button.
     * @param visible
     */
    public abstract void showBackButton(boolean visible);

    /**
     * Sets the visibility of the Home button.
     * @param visible
     */
    public abstract void showBackHome(boolean visible);

    /**
     * Sets the visibility of the title loading indicator.
     * @param visible
     */
    public abstract void showTitleLoading(boolean visible);

Close button

As shown in the red box, the Close button appears only in H5 scenarios. When the online page history, which is the browser history stack depth, exceeds one page, the container calls the showCloseButton method to control the button's visibility. When a user clicks this button, you must call the invokePageCloseEvent method to comply with standard container behavior.

Back button

The Back button, shown in the red box, is a required control in your custom navigation bar. The container calls the showBackButton method to control the button's visibility. When a user clicks the button, you must call the invokePageBackEvent method to comply with standard container behavior.

Home button

The Home button is used only in Mini Program scenarios. When a user navigates to a Mini Program page that is not the homepage, the container calls the showBackHome method to control the button's visibility. When a user clicks the button, you must call the invokeHomeClickEvent method to comply with standard container behavior.

Loading indicator

When an H5 page or Mini Program invokes the navigation bar loading animation API, the container calls the showTitleLoading method to control the visibility of the loading indicator.

Right control area

The right control area, also known as the OptionMenu control area, provides additional actions for users.

  • H5 container:

  • Mini Program:

As shown in the preceding images, you must reserve two view areas for the OptionMenu control area. The container operates these areas by index, from right to left, starting at 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);

The container controls the visibility of the OptionMenu area by calling the showOptionMenu method. In some cases, the container also needs to access the views in this area. Therefore, you must implement the getOptionMenuContainer method correctly.

When you implement the setOptionMenu method, refer to the parameters of the Set top-right buttons API. The icontype parameter defines built-in button styles and is available only in H5 scenarios. You can ignore this parameter if your integration does not use it. Otherwise, you must configure a button for each type. The redDot parameter works in a similar way to icontype, and its implementation is optional.

To allow H5 pages or Mini Programs to listen for top-right button clicks, call the invokeOptionClickEvent method.

Important

In Mini Program scenarios:

  • In the setOptionMenu method, the isTinyApp parameter is always true. This distinguishes Mini Program scenarios from H5 scenarios.

  • You must start setting buttons from the second button from the right.

Mini Program top-right control area

In a Mini Program scenario, you must implement the far-right area as follows:

  1. Inherit the AbsTinyOptionMenuView abstract class to implement your custom control area.

  2. At an appropriate time, such as during app startup, register your TinyOptionMenuViewProvider with the container.

    H5Utils.setProvider(TinyOptionMenuViewProvider.class.getName(), new TinyOptionMenuViewProvider() {
     @Override
     public AbsTinyOptionMenuView createView(Context context) {
         return new TinyOptionMenuView(context);
     }
    });

According to container specifications, you must implement and configure the More and Close button views.

    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();

The container calls the first three methods to set the appropriate response callbacks. You must ensure that your specified views register these callbacks.

The onStateChanged method is called in scenarios that involve location services or Bluetooth. For example, when a Mini Program uses location services, the container calls this method, and you can respond accordingly. The following image shows an example of the appearance.

Sample code:

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));
        }
    }
}

Theme changes

Different Mini Programs or H5 applications may set different background colors for the navigation bar. To ensure a consistent user experience, you must adjust other navigation bar elements, such as the top-right control area, when the background color changes.

In the navigation bar extension, the top-right control area and the navigation bar are separate components. Interfaces are provided to help developers ensure that the top-right control area responds promptly to navigation bar changes.

  • `AbsTinyOptionMenuView` provides the `onTitleChanged` method, which you can override to respond to navigation bar changes. When this method is called, you can obtain navigation bar information, such as the background color, from the passed H5TitleView object. Alternatively, you can use the getTitleBar method provided by AbsTinyOptionMenuView to retrieve the navigation bar object directly. You can also cast the H5TitleView to your own navigation bar implementation. Because AbsTitleView implements the H5TitleView interface, this gives you access to more navigation bar details.

      protected void onTitleChange(H5TitleView title)
  • Call the notifyTitleBarChanged method provided by AbsTitleView to trigger onTitleChange. For example, you can call this method when you set the navigation bar background color.

      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();
          }
      }

    In the preceding example, the subclass of AbsTinyOptionMenuView may not be fully initialized when notifyTitleBarChanged is called. Therefore, you must override the setH5Page method to obtain navigation bar information and determine the current theme, as shown in the following code:

      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);
              }
          }
      }