小程序可支持自定义导航栏,您可以根据需要制定导航栏的样式,例如标题的位置、返回按钮的样式等。本文将引导您基于 10.1.68 基线在使用小程序的过程中实现自定义导航栏。该过程主要分为以下三个步骤:
操作步骤
设置小程序的导航栏
打开 Android Studio,找到 assets > config 文件夹下的
custom_config.json
文件。添加如下代码,关闭小程序原生导航栏。{ "value": "NO", "key": "mp_ta_use_orginal_mini_nagivationbar" }
在 res > drawable 文件夹添加如下图所示的图片资源,点击此处 下载图片资源包。
右键单击 res 文件夹下的 layout 文件夹,选择 New > XML > Layout XML File,按 Enter 键。
在 Layout File Name 输入框中输入布局文件名称,单击 Finish。
在
h5_new_title_layout.xml
文件中添加如下代码,设置导航栏布局。<?xml version="1.0" encoding="utf-8"?> <com.alipay.mobile.nebula.view.H5TitleBarFrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/titlebar" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/il_layout" android:layout_width="match_parent" android:layout_height="52dp" android:layout_gravity="center_vertical"> <ImageView android:id="@+id/back" android:layout_width="26dp" android:layout_height="26dp" android:layout_gravity="center_vertical" android:layout_marginLeft="12dp" android:scaleType="centerInside" android:src="@drawable/icon_arrow_back" /> <ImageView android:id="@+id/home" android:layout_width="26dp" android:layout_height="26dp" android:layout_gravity="center_vertical" android:layout_marginLeft="12dp" android:scaleType="centerInside" android:src="@drawable/icon_miniprogram_home" android:visibility="gone" /> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center_horizontal" android:orientation="vertical"> <TextView android:id="@+id/mainTitle" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:textColor="@android:color/white" android:textSize="20sp" /> <TextView android:id="@+id/subTitle" android:layout_width="wrap_content" android:layout_height="match_parent" android:visibility="visible" /> </LinearLayout> <FrameLayout android:id="@+id/options1" android:layout_width="wrap_content" android:layout_height="match_parent" android:visibility="gone"> <ImageView android:id="@+id/o1image" android:layout_width="26dp" android:layout_height="26dp" android:layout_gravity="center_vertical" /> </FrameLayout> <LinearLayout android:id="@+id/options" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center_vertical" android:layout_marginRight="12dp" android:orientation="horizontal" android:visibility="gone" /> </LinearLayout> </com.alipay.mobile.nebula.view.H5TitleBarFrameLayout>
创建 TinyNavigationBar 类。
在 TinyNavigationBar 类中添加如下代码实现自定义 Title Bar。
public class TinyNavigationBar extends AbsTitleView { private H5TitleBarFrameLayout content; private TextView mainTitleView; private TextView subTitleView; private View btnBack; private View optionContainer; private View options1; private View btHome; private Context context; public TinyNavigationBar(Context context) { ViewGroup parent = null; this.context = context; if (context instanceof Activity) { parent = (ViewGroup) ((Activity) context).findViewById(android.R.id.content); } content = (H5TitleBarFrameLayout) LayoutInflater.from(context).inflate(R.layout.h5_new_title_layout, parent, false); content.getContentBgView().setColor(context.getResources().getColor(R.color.colorPrimary)); mainTitleView = (TextView) content.findViewById(R.id.mainTitle); subTitleView = (TextView) content.findViewById(R.id.subTitle); btnBack = content.findViewById(R.id.back); btnBack.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { invokePageBackEvent(); } }); optionContainer = content.findViewById(R.id.options); btHome = content.findViewById(R.id.home); int statusBarHeight = H5StatusBarUtils.getStatusBarHeight(context); content.setPadding(0, statusBarHeight, 0, 0); btHome.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { invokeHomeClickEvent(); } }); options1 = content.findViewById(R.id.options1); options1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { invokeOptionClickEvent(1, false); } }); } @Override public int getBackgroundColor() { return content.getContentBgView().getColor(); } @Override public void setBackgroundAlphaValue(int i) { content.getContentBgView().setAlpha(i); } @Override public void setBackgroundColor(int i) { if ((i & 0xffffff) == 0xffffff) { mainTitleView.setTextColor(Color.BLACK); } else { mainTitleView.setTextColor(Color.WHITE); } content.getContentBgView().setColor(i); notifyTitleBarChanged(); } @Override public String getTitle() { return mainTitleView.getText().toString(); } @Override public void setTitle(String s) { mainTitleView.setText(s); } @Override public void setSubTitle(String s) { subTitleView.setText(s); } @Override public void setTitleImage(Bitmap bitmap) { } @Override public TextView getMainTitleView() { return mainTitleView; } @Override public TextView getSubTitleView() { return subTitleView; } @Override public void resetTitle() { content.getContentBgView().setColor(context.getResources().getColor(R.color.colorPrimary)); } @Override public void showCloseButton(boolean b) { } @Override public View getContentView() { return content; } @Override public void showBackButton(boolean b) { btnBack.setVisibility(b ? View.VISIBLE : View.GONE); } @Override public void showBackHome(boolean b) { btHome.setVisibility(b ? View.VISIBLE : View.GONE); } @Override public void showOptionMenu(boolean b) { optionContainer.setVisibility(b ? View.VISIBLE : View.GONE); options1.setVisibility(b ? View.VISIBLE : View.GONE); } @Override public View getOptionMenuContainer(int i) { if (i == 1) { return options1; } return optionContainer; } @Override public void setOptionMenu(boolean reset, boolean override, boolean isTinyApp, List<MenuData> menus) { for (int i = 0; i < 2 && i < menus.size(); i++) { MenuData menuData = menus.get(i); if (isTinyApp) { String iconUrl = menuData.getIcon(); if (!TextUtils.isEmpty(iconUrl)) { H5ImageUtil.loadImage(iconUrl, new H5ImageListener() { @Override public void onImage(Bitmap bitmap) { ((ImageView)options1.findViewById(R.id.o1image)).setImageBitmap(bitmap); } }); } } } } @Override public void showTitleLoading(boolean b) { } @Override public View getPopAnchor() { return optionContainer; } }
设置小程序的 OptionMenu
右键单击 res 文件夹下的 layout 文件夹,选择 New > XML > Layout XML File,按 Enter 键。
输入 Layout File Name,单击 Finish。
在
layout_tiny_right.xml
文件中添加如下代码,设置 OptionMenu 控制区的布局。<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="center_vertical"> <LinearLayout android:id="@+id/option_bg" android:background="#9fffffff" android:layout_width="wrap_content" android:layout_height="42dp" android:layout_gravity="center_vertical" android:gravity="center_vertical"> <ImageView android:id="@+id/more" android:layout_width="26dp" android:layout_height="26dp" android:src="@drawable/icon_more"/> <ImageView android:id="@+id/close" android:layout_width="26dp" android:layout_height="26dp" android:layout_marginLeft="12dp" android:src="@drawable/icon_miniprogram_close"/> </LinearLayout> </FrameLayout>
创建 TinyOptionMenuView 类。
在 TinyOptionMenuView 类中添加如下代码实现自定义 OptionMenu 控制区。
public class TinyOptionMenuView extends AbsTinyOptionMenuView { private View container; private ImageView ivMore; private View ivClose; private Context context; private View bgView; 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); bgView = container.findViewById(R.id.option_bg); } @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)); } } @Override protected void onTitleChange(final H5TitleView title) { super.onTitleChange(title); int color = title.getBackgroundColor(); if ((color & 0xffffff) == 0xffffff) { bgView.setBackgroundColor(Color.RED); } else { bgView.setBackgroundColor(Color.GREEN); } } @Override public void setH5Page(H5Page h5Page) { super.setH5Page(h5Page); // title becomes available from here. if (getTitleBar().getBackgroundColor() == -1) { bgView.setBackgroundColor(Color.RED); } } @Override public void hideOptionMenu() { } }
在 MyApplication 类中的 IInitCallback 初始化回调中添加如下代码实现自定义标题栏和自定义右上角配置栏。
// 自定义标题栏 MPNebula.setCustomViewProvider(new H5ViewProvider() { @Override public H5TitleView createTitleView(Context context) { // 返回自定义 title return new TinyNavigationBar(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; } }); // 自定义小程序右上角配置栏 H5Utils.setProvider(TinyOptionMenuViewProvider.class.getName(), new TinyOptionMenuViewProvider() { @Override public AbsTinyOptionMenuView createView(Context context) { return new TinyOptionMenuView(context); } });
运行小程序查看设置后的导航栏和 OptionMenu
单击 运行程序到真机上。
单击 Hello World! 启动小程序。打开应用后在小程序加载时界面如下,可以看到自定义的右上角配置栏。
单击 基础组件 下的 图标 可以看到 Icon 页中的自定义导航栏布局。