To customize the navigation bar of an HTML5 container in baseline 10.1.60, refer to the following sample code:
H5TitleViewImpl.java
package com.mpaas.demo.nebula;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alipay.mobile.h5container.api.H5Page;
import com.alipay.mobile.h5container.api.H5Param;
import com.alipay.mobile.h5container.api.H5Plugin;
import com.alipay.mobile.nebula.util.H5Log;
import com.alipay.mobile.nebula.util.H5StatusBarUtils;
import com.alipay.mobile.nebula.util.H5Utils;
import com.alipay.mobile.nebula.view.H5TitleBarFrameLayout;
import com.alipay.mobile.nebula.view.H5TitleView;
import com.alipay.mobile.nebula.view.IH5TinyPopMenu;
import java.util.ArrayList;
import java.util.List;
/**
* Created by omg on 2018/7/23.
*/
public class H5TitleViewImpl implements H5TitleView, View.OnClickListener {
private static final String TAG = "H5TitleViewImpl";
private Context mContext;
private H5TitleBarFrameLayout contentView;
private String title;
// Define the basic controls of the title bar here.
private TextView mTitleView;
private TextView mSubTitleView;
private View mCloseButton;
private View mBackButton;
private View vDivider;
private View hDivider;
private View statusBarAdjustView;
/**
* ==== Start of various views for OptionMenu ====
*/
// Container for OptionMenu
public View h5NavOptions;
public View h5NavOptions1;
public List<View> h5NavOptionsList = new ArrayList<View>();
// ---- Start of the three forms of OptionMenu ---- //
// 1. OptionType.MENU (default) - The default Option button
public TextView btMenu;
public TextView btMenu1;
public List<TextView> btMenuList = new ArrayList<TextView>();
// 2. OptionType.ICON - The icon manually set by setOptionMenu
public ImageButton btIcon;
public ImageButton btIcon1;
public List<ImageButton> btIconList = new ArrayList<ImageButton>();
// 3. OptionType.TEXT - Text
public TextView btText;
public TextView btText1;
public List<TextView> btTextList = new ArrayList<TextView>();
// ---- End of the three forms of OptionMenu ---- //
// The instance interface class of the web page, which can be used to control web behavior.
private H5Page h5Page;
private int visibleOptionNum = 0;
private IH5TinyPopMenu h5TinyPopMenu;
/**
* Constructor for the HTML5 container title bar.
* Note: The root vertex of the title bar layout XML file must be H5TitleBarFrameLayout.
* @param context
*/
public H5TitleViewImpl(Context context) {
mContext = context;
ViewGroup parent = null;
if (context instanceof Activity) {
parent = (ViewGroup) ((Activity) mContext).findViewById(android.R.id.content);
}
contentView = (H5TitleBarFrameLayout) LayoutInflater.from(context).inflate(R.layout.h5_navigation_bar, parent, false);
contentView.getContentBgView().setColor(context.getResources().getColor(R.color.h5_default_titlebar_color));
mTitleView = (TextView) contentView.findViewById(R.id.h5_tv_title);
mTitleView.setOnClickListener(this);
mSubTitleView = (TextView) contentView.findViewById(R.id.h5_tv_subtitle);
mSubTitleView.setOnClickListener(this);
mCloseButton = contentView.findViewById(R.id.h5_nav_close);
mCloseButton.setOnClickListener(this);
mBackButton = contentView.findViewById(R.id.h5_tv_nav_back);
mBackButton.setOnClickListener(this);
vDivider = contentView.findViewById(R.id.h5_v_divider);
hDivider = contentView.findViewById(R.id.h5_h_divider_intitle);
h5NavOptions = contentView.findViewById(R.id.h5_nav_options);
h5NavOptions1 = contentView.findViewById(R.id.h5_nav_options1);
statusBarAdjustView = contentView.findViewById(R.id.h5_status_bar_adjust_view);
btIcon = (ImageButton) contentView.findViewById(R.id.h5_bt_image);
btText = (TextView) contentView.findViewById(R.id.h5_bt_text);
btMenu = (TextView) contentView.findViewById(R.id.h5_bt_options);
btIcon1 = (ImageButton) contentView.findViewById(R.id.h5_bt_image1);
btText1 = (TextView) contentView.findViewById(R.id.h5_bt_text1);
btMenu1 = (TextView) contentView.findViewById(R.id.h5_bt_options1);
// Add the view to the list.
h5NavOptionsList.add(h5NavOptions);
h5NavOptionsList.add(h5NavOptions1);
btIconList.add(btIcon);
btIconList.add(btIcon1);
btTextList.add(btText);
btTextList.add(btText1);
btMenuList.add(btMenu);
btMenuList.add(btMenu1);
btText.setOnClickListener(this);
btIcon.setOnClickListener(this);
btText1.setOnClickListener(this);
btIcon1.setOnClickListener(this);
btMenu.setOnClickListener(this);
btMenu1.setOnClickListener(this);
}
/**
* The container calls this method to get the main title content.
*/
@Override
public String getTitle() {
return title;
}
/**
* The container calls this method to set the main title content.
*/
@Override
public void setTitle(String s) {
title = s;
mTitleView.setText(s);
}
/**
* The container calls this method to set the subtitle content.
*/
@Override
public void setSubTitle(String s) {
mSubTitleView.setVisibility(View.VISIBLE);
mSubTitleView.setText(s);
}
/**
* Ignore for now. Implementation is optional.
*/
@Override
public void setImgTitle(Bitmap bitmap) {
}
/**
* Ignore for now. Implementation is optional.
*/
@Override
public void setImgTitle(Bitmap bitmap, String s) {
}
/**
* The container sets whether to display the Close button.
*/
@Override
public void showCloseButton(boolean b) {
mCloseButton.setVisibility(b ? View.VISIBLE : View.GONE);
}
/**
* The container gets the title bar View.
*/
@Override
public View getContentView() {
return contentView;
}
/**
* The container gets the title bar background to set the background color.
*/
@Override
public ColorDrawable getContentBgView() {
return contentView.getContentBgView();
}
/**
* The container gets the main title View.
* This cannot be empty.
*/
@Override
public TextView getMainTitleView() {
return mTitleView;
}
/**
* The container gets the subtitle View.
* This cannot be empty.
*/
@Override
public TextView getSubTitleView() {
return mSubTitleView;
}
/**
* Set whether to display the back button.
*/
@Override
public void showBackButton(boolean b) {
mBackButton.setVisibility(b ? View.VISIBLE : View.GONE);
}
/**
* Set whether to display the menu item in the upper-right corner.
*/
@Override
public void showOptionMenu(boolean isShow) {
if (isShow) {
switch (visibleOptionNum) {
case 1:
h5NavOptions.setVisibility(View.VISIBLE);
break;
case 2:
h5NavOptions.setVisibility(View.VISIBLE);
h5NavOptions1.setVisibility(View.VISIBLE);
break;
}
} else {
h5NavOptions.setVisibility(View.GONE);
h5NavOptions1.setVisibility(View.GONE);
}
}
/**
* Set the display type of the menu item in the upper-right corner. The type can be an icon or text.
*/
@Override
public void setOptionType(H5Param.OptionType optionType) {
setOptionType(optionType, 0, true);
}
/**
* Set the display type of the menu item in the upper-right corner. The type can be an icon or text.
* @param byIndex Specifies whether to set the display type for only a specific menu item.
*/
@Override
public void setOptionType(H5Param.OptionType type, int num, boolean byIndex) {
boolean icon = false;
boolean text = false;
boolean menu = false;
if (type == H5Param.OptionType.ICON) {
icon = true;
} else if (type == H5Param.OptionType.TEXT) {
text = true;
} else if (type == H5Param.OptionType.MENU) {
menu = true;
}
ctrlbtText(num, text ? View.VISIBLE : View.GONE, byIndex);
ctrlbtIcon(num, icon ? View.VISIBLE : View.INVISIBLE, byIndex);
ctrlbtMenu(num, menu ? View.VISIBLE : View.INVISIBLE, byIndex);
}
// Control view visibility.
private boolean isOutOfBound(int num, int length) {
if (length == 0) {
return true;
}
return length < num;
}
private void ctrlbtText(int num, int visible, boolean byIndex) {
if (isOutOfBound(num, btTextList.size())) {
return;
}
if (byIndex) {
btTextList.get(num).setVisibility(visible);
} else {
for (int i = 0; i < num; i++) {
btTextList.get(i).setVisibility(visible);
}
}
}
private void ctrlbtIcon(int num, int visible, boolean byIndex) {
if (isOutOfBound(num, btIconList.size())) {
return;
}
if (byIndex) {
btIconList.get(num).setVisibility(visible);
} else {
for (int i = 0; i < num; i++) {
btIconList.get(i).setVisibility(visible);
}
}
}
private void ctrlbtMenu(int num, int visible, boolean byIndex) {
if (isOutOfBound(num, btMenuList.size())) {
return;
}
if (byIndex) {
btMenuList.get(num).setVisibility(visible);
} else {
for (int i = 0; i < num; i++) {
btMenuList.get(i).setVisibility(visible);
}
}
}
/**
* Set whether to display the loading status on the title bar. You can choose the implementation method.
*/
@Override
public void showTitleLoading(boolean b) {
}
/**
* Can be ignored.
*/
@Override
public void showTitleDisclaimer(boolean b) {
}
// Set the icon for the button in the upper-right corner.
@Override
public void setBtIcon(Bitmap btIcon, int index) {
if (isOutOfBound(index, btIconList.size())) {
return;
}
btIconList.get(index).setImageBitmap(btIcon);
}
@Override
public void setH5Page(H5Page h5Page) {
this.h5Page = h5Page;
}
/**
* Set the menu in the upper-right corner based on the parameters passed from JavaScript (JS).
*/
@Override
public void setOptionMenu(JSONObject params) {
boolean reset = H5Utils.getBoolean(params, "reset", false);
boolean override = H5Utils.getBoolean(params, "override", false);
JSONArray menus = H5Utils.getJSONArray(params, "menus", null);
if (reset) {
h5NavOptions1.setVisibility(View.GONE);
setOptionType(H5Param.OptionType.MENU, 0, true);
visibleOptionNum = 1;
return;
}
if (menus != null && !menus.isEmpty()) {
visibleOptionNum = 0;
if (override) {
int menuSize = menus.size() > 2 ? 2 : menus.size();
for (int i = 0; i < menuSize; i++) {
// h5NavOptionsList.get(i).setVisibility(View.VISIBLE);
JSONObject menusItem = menus.getJSONObject(i);
setOptionMenuInternal(menusItem, i);
visibleOptionNum++;
}
} else {
visibleOptionNum = 2;
// h5NavOptionsList.get(1).setVisibility(View.VISIBLE);
JSONObject menusItem = menus.getJSONObject(0);
setOptionMenuInternal(menusItem, 1);
}
} else {
setOptionMenuInternal(params, 0);
visibleOptionNum = 1;
}
}
private void setOptionMenuInternal(JSONObject params, int index) {
String title = H5Utils.getString(params, "title");
String icon = H5Utils.getString(params, "icon");
String icontype = H5Utils.getString(params, "icontype");
String contentDesc = H5Utils.getString(params, "contentDesc");
String colorText = H5Utils.getString(params, "color");
// Default white color.
int color = 0xFF108ee9;
if (!TextUtils.isEmpty(colorText)) {
try {
color = Color.parseColor(colorText);
} catch (Throwable ignore) {
// Cannot find logutil.
}
color = 0xFF000000 | color;
btTextList.get(index).setTextColor(color);
} else {
int currentColor = mTitleView.getCurrentTextColor();
currentColor = 0xFF000000 | currentColor;
H5Log.d(TAG, "setOptionMenuInternal currentColor is " + currentColor);
if (currentColor != 0xFF111111) {
btText.setTextColor(0xFFFFFFFF);
btText1.setTextColor(0xFFFFFFFF);
} else {
btText.setTextColor(0xFF108ee9);
btText1.setTextColor(0xFF108ee9);
}
}
if (!TextUtils.isEmpty(title)) {
title = title.trim();
btTextList.get(index).setText(title);
setOptionType(H5Param.OptionType.TEXT, index, true);
btTextList.get(index).setContentDescription(title);
} else if (!TextUtils.isEmpty(icon) || !TextUtils.isEmpty(icontype)) {
if (!TextUtils.isEmpty(contentDesc)) {
btIconList.get(index).setContentDescription(contentDesc);
}
}
}
/**
* The container gets the line separator between the back button and the title content.
* Can return empty.
*/
@Override
public View getDivider() {
return vDivider;
}
/**
* The container gets the line separator between the title bar and the web page.
* This cannot be empty.
*/
@Override
public View getHdividerInTitle() {
return hDivider;
}
/**
* The container gets the anchor View for the pop-up position of the drop-down menu.
*/
@Override
public View getPopAnchor() {
return btMenu;
}
/**
* The container resets the background color of the title bar.
*/
@Override
public void resetTitleColor(int color) {
}
/**
* Ignore for now.
*/
@Override
public void switchToWhiteTheme() {
}
/**
* Ignore for now.
*/
@Override
public void switchToBlueTheme() {
}
/**
* Triggered when the container page is destroyed. You can release the referenced View here.
*/
@Override
public void releaseViewList() {
if (h5NavOptionsList != null) {
h5NavOptionsList.clear();
}
if (btIconList != null) {
btIconList.clear();
}
if (btTextList != null) {
btTextList.clear();
}
if (btMenuList != null) {
btMenuList.clear();
}
}
/**
* The container sets the color of the immersive title bar.
*/
@Override
public void openTranslucentStatusBarSupport(int color) {
if (H5StatusBarUtils.isSupport()) {
int statusBarHeight = H5StatusBarUtils.getStatusBarHeight(mContext);
if (statusBarHeight == 0) { // A safeguard in case a ROM cannot get the status bar height. The setting will not take effect.
return;
}
LinearLayout.LayoutParams layoutParams =
(LinearLayout.LayoutParams) statusBarAdjustView.getLayoutParams();
layoutParams.height = statusBarHeight;
statusBarAdjustView.setLayoutParams(layoutParams);
statusBarAdjustView.setVisibility(View.VISIBLE);
try {
H5StatusBarUtils.setTransparentColor((Activity) mContext, color);
} catch (Exception e) {
H5Log.e(TAG, e);
}
}
}
/**
* Ignore for now.
*/
@Override
public void switchToTitleBar() {
}
/**
* Ignore for now.
*/
@Override
public View setTitleBarSearch(Bundle bundle) {
return null;
}
/**
* Ignore for now.
*/
@Override
public void setBackCloseBtnImage(String s) {
}
/**
* Set the font color of the title bar.
*/
@Override
public void setTitleTxtColor(int i) {
mTitleView.setTextColor(i);
mSubTitleView.setTextColor(i);
}
/**
* The container gets the menu View in the upper-right corner. It must be a ViewGroup or its child class.
*/
@Override
public View getOptionMenuContainer() {
return h5NavOptions;
}
/**
* The container gets the menu View in the upper-right corner by position. It must be a ViewGroup or its child class.
*/
@Override
public View getOptionMenuContainer(int index) {
switch (index) {
case 0:
return h5NavOptions;
case 1:
return h5NavOptions1;
default:
return getOptionMenuContainer();
}
}
/**
* Ignore for now.
*/
@Override
public void setIH5TinyPopMenu(IH5TinyPopMenu tinyPopMenu) {
this.h5TinyPopMenu = tinyPopMenu;
}
/**
* Ignore for now.
*/
@Override
public IH5TinyPopMenu getH5TinyPopMenu() {
return null;
}
/**
* Ignore for now.
*/
@Override
public void setTitleView(View view) {
}
/**
* Ignore for now.
*/
@Override
public void initTitleSegControl(JSONObject jsonObject) {
}
/**
* Ignore for now.
*/
@Override
public void enableTitleSegControl(boolean b) {
}
/**
* Ignore for now.
*/
@Override
public void enableBackButtonBackground(boolean b) {
}
/**
* Handles click events for different controls on the title bar.
* If JS needs to receive events, send the events to JS as shown in this code.
* For example, if the back button is clicked, send the H5Plugin.CommonEvents.H5_TOOLBAR_BACK event.
*/
@Override
public void onClick(View view) {
if (h5Page == null) {
return ;
}
String eventName = null;
JSONObject data = null;
if (view == mBackButton) {
eventName = H5Plugin.CommonEvents.H5_TOOLBAR_BACK; // Send a back event.
} else if (view == mCloseButton) {
eventName = H5Plugin.CommonEvents.H5_TOOLBAR_CLOSE; // Send a close page event.
}else if (view.equals(btIcon) || view.equals(btText)) {
eventName = H5Plugin.CommonEvents.H5_TITLEBAR_OPTIONS;
data = new JSONObject();
data.put("index", 0);
} else if (view.equals(btIcon1) || view.equals(btText1)) {
eventName = H5Plugin.CommonEvents.H5_TITLEBAR_OPTIONS;
data = new JSONObject();
data.put("index", 1);
} else if (view.equals(btMenu) || view.equals(btMenu1)) {
eventName = H5Plugin.CommonEvents.H5_TITLEBAR_OPTIONS;
data = new JSONObject();
data.put("fromMenu", true);
data.put("index", view.equals(btMenu) ? 0 : 1);
} else if (view.equals(mTitleView)) {
eventName = H5Plugin.CommonEvents.H5_TITLEBAR_TITLE;
} else if (view.equals(mSubTitleView)) {
eventName = H5Plugin.CommonEvents.H5_TITLEBAR_SUBTITLE;
}
if (!TextUtils.isEmpty(eventName)) {
h5Page.sendEvent(eventName, data);
}
}
}h5_navigation_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<com.alipay.mobile.nebula.view.H5TitleBarFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/h5_title_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent">
<LinearLayout
android:id="@+id/h5_rl_title_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:orientation="vertical">
<View
android:id="@+id/h5_status_bar_adjust_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
<RelativeLayout
android:id="@+id/h5_title_bar_layout"
android:layout_width="match_parent"
android:layout_height="48dp">
<ImageButton
android:id="@+id/h5_tv_nav_back"
android:layout_width="48dp"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:background="@android:color/transparent"
android:scaleType="centerInside"
android:padding="12dp"
android:src="@drawable/back"/>
<ImageButton
android:id="@+id/h5_nav_close"
android:layout_width="48dp"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:padding="12dp"
android:layout_marginLeft="-6dp"
android:layout_toRightOf="@+id/h5_tv_nav_back"
android:background="@android:color/transparent"
android:clickable="true"
android:scaleType="centerInside"
android:src="@drawable/close"/>
<View
android:id="@+id/h5_v_divider"
android:layout_width="0.7dp"
android:layout_height="24dp"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:layout_marginRight="12dp"
android:layout_toRightOf="@+id/h5_nav_close"
tools:ignore="ContentDescription"/>
<RelativeLayout
android:id="@+id/h5_rl_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center">
<LinearLayout
android:id="@+id/h5_ll_title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/h5_tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textColor="@android:color/white"
android:textSize="16dp" />
<ImageView
android:id="@+id/h5_tv_title_img"
android:layout_width="wrap_content"
android:layout_height="36dp"
android:scaleType="centerInside"
android:visibility="gone"/>
</FrameLayout>
<TextView
android:id="@+id/h5_tv_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textColor="@android:color/white"
android:textSize="12dp"
android:visibility="gone"
tools:visibility="visible" />
</LinearLayout>
</RelativeLayout>
<!-- optionmenu0 -->
<FrameLayout
android:id="@+id/h5_nav_options"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginLeft="6dp">
<ImageButton
android:id="@+id/h5_bt_image"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="center|right"
android:layout_marginRight="12dp"
android:background="@android:color/transparent"
android:padding="4dp"
android:scaleType="fitCenter"
android:visibility="gone"/>
<TextView
android:id="@+id/h5_bt_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|right"
android:layout_marginRight="12dp"
android:background="@null"
android:ellipsize="end"
android:maxLength="8"
android:singleLine="true"
android:textColor="#ffffff"
android:textSize="16dp"/>
<TextView
android:id="@+id/h5_bt_options"
android:layout_width="48dp"
android:layout_height="match_parent"
android:background="@null"
android:gravity="center"
android:textSize="23dp"
android:visibility="gone"
tools:visibility="gone" />
</FrameLayout>
<!-- optionmenu1 -->
<FrameLayout
android:id="@+id/h5_nav_options1"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_centerVertical="true"
android:layout_marginLeft="6dp"
android:layout_toLeftOf="@id/h5_nav_options"
android:visibility="gone"
tools:visibility="visible">
<ImageButton
android:id="@+id/h5_bt_image1"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="center|right"
android:layout_marginRight="12dp"
android:background="@android:color/transparent"
android:padding="4dp"
android:scaleType="fitCenter"
android:visibility="gone"/>
<TextView
android:id="@+id/h5_bt_text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|right"
android:layout_marginRight="12dp"
android:background="@null"
android:ellipsize="end"
android:maxLength="8"
android:singleLine="true"
android:textColor="#108ee9"
android:textSize="16dp"/>
</FrameLayout>
</RelativeLayout>
<View
android:id="@+id/h5_h_divider_intitle"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@android:color/white"
android:visibility="gone"/>
</LinearLayout>
</com.alipay.mobile.nebula.view.H5TitleBarFrameLayout>