If you need to customize HTML5 container title bar, refer to the following code samples:
10.1.60
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
private TextView mTitleView;
private TextView mSubTitleView;
private View mCloseButton;
private View mBackButton;
private View vDivider;
private View hDivider;
private View statusBarAdjustView;
/**
* ==== Each View of OptionMenu. Start ====
*/
// Container of OptionMenu
public View h5NavOptions;
public View h5NavOptions1;
public List<View> h5NavOptionsList = new ArrayList<View>();
// ---- Three typs of OptionMenu. Start ---- //
// 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 via setOptionMenu.
public ImageButton btIcon;
public ImageButton btIcon1;
public List<ImageButton> btIconList = new ArrayList<ImageButton>();
// 3. OptionType.TEXT - test
public TextView btText;
public TextView btText1;
public List<TextView> btTextList = new ArrayList<TextView>();
// ---- Three typs of OptionMenu. Over ---- //
// Instance interface class of Web page, used to control web action
private H5Page h5Page;
private int visibleOptionNum = 0;
private IH5TinyPopMenu h5TinyPopMenu;
/**
* The method to construct HTML5 container title bar
* Note: Title bar layout xml file must have H5TitleBarFrameLayout as the root node.
* @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 view to 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);
}
/**
* Container calls this method to obtain the content of the main title.
*/
@Override
public String getTitle() {
return title;
}
/**
* Container calls this method to set the content of the main title.
*/
@Override
public void setTitle(String s) {
title = s;
mTitleView.setText(s);
}
/**
* Container calls this method to set the content of the sub title.
*/
@Override
public void setSubTitle(String s) {
mSubTitleView.setVisibility(View.VISIBLE);
mSubTitleView.setText(s);
}
/**
* Ignore for now, not necessary.
*/
@Override
public void setImgTitle(Bitmap bitmap) {
}
/**
* Ignore for now, not necessary.
*/
@Override
public void setImgTitle(Bitmap bitmap, String s) {
}
/**
* Set whether to dispaly the close button for the container.
*/
@Override
public void showCloseButton(boolean b) {
mCloseButton.setVisibility(b ? View.VISIBLE : View.GONE);
}
/**
* Container obtains title bar View.
*/
@Override
public View getContentView() {
return contentView;
}
/**
* Container obtains title bar background for setting background color.
*/
@Override
public ColorDrawable getContentBgView() {
return contentView.getContentBgView();
}
/**
* Container obtains main title View.
* Cannot be empty
*/
@Override
public TextView getMainTitleView() {
return mTitleView;
}
/**
* Container obtains subtitle View.
* Cannot be empty
*/
@Override
public TextView getSubTitleView() {
return mSubTitleView;
}
/**
* Set whether to display back button.
*/
@Override
public void showBackButton(boolean b) {
mBackButton.setVisibility(b ? View.VISIBLE : View.GONE);
}
/**
* Set whether to display the top right menu.
*/
@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);
}
}
/**
* Seth the display type of the top right menu, which can be icon or text.
*/
@Override
public void setOptionType(H5Param.OptionType optionType) {
setOptionType(optionType, 0, true);
}
/**
* Seth the display type of the top right menu, which can be icon or text.
* @param byIndex : whether to set the display type only for a certain menu.
*/
@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);
}
//view visible control
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 impletment method yourself.
*/
@Override
public void showTitleLoading(boolean b) {
}
/**
* Ignore for now
*/
@Override
public void showTitleDisclaimer(boolean b) {
}
// Set the icon of the top right button.
@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 top right menu according to the parameters passed from 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) {
//can not 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);
}
}
}
/**
* Container obtais the split line between the back button and the title content.
* The return value can be empty.
*/
@Override
public View getDivider() {
return vDivider;
}
/**
* Container obtains the split line between the title bar and Web page.
* Cannot be empty
*/
@Override
public View getHdividerInTitle() {
return hDivider;
}
/**
* Container obtains the anchor view of pull-down menu pop-up position.
*/
@Override
public View getPopAnchor() {
return btMenu;
}
/**
* Container resets the background color of title bar.
*/
@Override
public void resetTitleColor(int color) {
}
/**
* Ignore for now
*/
@Override
public void switchToWhiteTheme() {
}
/**
* Ignore for now
*/
@Override
public void switchToBlueTheme() {
}
/**
* Triggered when container page is distroyed. The referred View can be released 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();
}
}
/**
* Container sets the color of translucent title bar
*/
@Override
public void openTranslucentStatusBarSupport(int color) {
if (H5StatusBarUtils.isSupport()) {
int statusBarHeight = H5StatusBarUtils.getStatusBarHeight(mContext);
if (statusBarHeight == 0) { //Protection. In case rom cannot get the height of status bar, it doesn't take effect here.
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 title bar
*/
@Override
public void setTitleTxtColor(int i) {
mTitleView.setTextColor(i);
mSubTitleView.setTextColor(i);
}
/**
* Container obtains the top right menu View, which must be ViewGroup and its sub-class.
*/
@Override
public View getOptionMenuContainer() {
return h5NavOptions;
}
/**
* According to the position, container obtains the top right menu View, which must be ViewGroup and its sub-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) {
}
/**
* Handle the click events of different controls on the title bar
* If JS needs to receive events, the events need to be sent to JS as shown in the code.
* For example, clicking the back button will 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 back event
} else if (view == mCloseButton) {
eventName = H5Plugin.CommonEvents.H5_TOOLBAR_CLOSE; // Send closing 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>