全部产品

自定义导航栏

更新时间:2021-03-11 14:46:17

小程序可支持自定义导航栏,您可以自行制定导航栏的样式,例如标题的位置、返回按钮的样式等。本文将引导您基于 10.1.68 基线在使用小程序的过程中实现自定义导航栏。
该过程主要分为以下三个步骤:

  1. 设置小程序的导航栏
  2. 设置小程序的 OptionMenu
  3. 运行小程序查看设置后的导航栏和 OptionMenu

操作步骤

设置小程序的导航栏

  1. 打开 Android Studio,找到 assets > config 文件夹下的 custom_config.json 文件。添加如下代码,关闭小程序原生导航栏。

    1. {
    2. "value": "NO",
    3. "key": "mp_ta_use_orginal_mini_nagivationbar"
    4. }
  2. res > drawable 文件夹添加如下图所示的图片资源,点击此处 下载图片资源包。
    1
  3. 右键单击 res 文件夹下的 layout 文件夹,选择 New > XML > Layout XML File,按 Enter 键。
    1
  4. Layout File Name 输入框中输入布局文件名称,单击 Finish
    2
  5. h5_new_title_layout.xml 文件中添加如下代码,设置导航栏布局。

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <com.alipay.mobile.nebula.view.H5TitleBarFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3. android:id="@+id/titlebar"
    4. android:layout_width="match_parent"
    5. android:layout_height="match_parent">
    6. <LinearLayout
    7. android:id="@+id/il_layout"
    8. android:layout_width="match_parent"
    9. android:layout_height="52dp"
    10. android:layout_gravity="center_vertical">
    11. <ImageView
    12. android:id="@+id/back"
    13. android:layout_width="26dp"
    14. android:layout_height="26dp"
    15. android:layout_gravity="center_vertical"
    16. android:layout_marginLeft="12dp"
    17. android:scaleType="centerInside"
    18. android:src="@drawable/icon_arrow_back" />
    19. <ImageView
    20. android:id="@+id/home"
    21. android:layout_width="26dp"
    22. android:layout_height="26dp"
    23. android:layout_gravity="center_vertical"
    24. android:layout_marginLeft="12dp"
    25. android:scaleType="centerInside"
    26. android:src="@drawable/icon_miniprogram_home"
    27. android:visibility="gone" />
    28. <LinearLayout
    29. android:layout_width="0dp"
    30. android:layout_height="match_parent"
    31. android:layout_weight="1"
    32. android:gravity="center_horizontal"
    33. android:orientation="vertical">
    34. <TextView
    35. android:id="@+id/mainTitle"
    36. android:layout_width="wrap_content"
    37. android:layout_height="match_parent"
    38. android:gravity="center"
    39. android:textColor="@android:color/white"
    40. android:textSize="20sp" />
    41. <TextView
    42. android:id="@+id/subTitle"
    43. android:layout_width="wrap_content"
    44. android:layout_height="match_parent"
    45. android:visibility="visible" />
    46. </LinearLayout>
    47. <FrameLayout
    48. android:id="@+id/options1"
    49. android:layout_width="wrap_content"
    50. android:layout_height="match_parent"
    51. android:visibility="gone">
    52. <ImageView
    53. android:id="@+id/o1image"
    54. android:layout_width="26dp"
    55. android:layout_height="26dp"
    56. android:layout_gravity="center_vertical" />
    57. </FrameLayout>
    58. <LinearLayout
    59. android:id="@+id/options"
    60. android:layout_width="wrap_content"
    61. android:layout_height="match_parent"
    62. android:layout_gravity="center_vertical"
    63. android:layout_marginRight="12dp"
    64. android:orientation="horizontal"
    65. android:visibility="gone" />
    66. </LinearLayout>
    67. </com.alipay.mobile.nebula.view.H5TitleBarFrameLayout>
  6. 创建 TinyNavigationBar 类。
    4
  7. 在 TinyNavigationBar 类中添加如下代码实现自定义 Title Bar。

    1. public class TinyNavigationBar extends AbsTitleView {
    2. private H5TitleBarFrameLayout content;
    3. private TextView mainTitleView;
    4. private TextView subTitleView;
    5. private View btnBack;
    6. private View optionContainer;
    7. private View options1;
    8. private View btHome;
    9. private Context context;
    10. public TinyNavigationBar(Context context) {
    11. ViewGroup parent = null;
    12. this.context = context;
    13. if (context instanceof Activity) {
    14. parent = (ViewGroup) ((Activity) context).findViewById(android.R.id.content);
    15. }
    16. content = (H5TitleBarFrameLayout) LayoutInflater.from(context).inflate(R.layout.h5_new_title_layout, parent, false);
    17. content.getContentBgView().setColor(context.getResources().getColor(R.color.colorPrimary));
    18. mainTitleView = (TextView) content.findViewById(R.id.mainTitle);
    19. subTitleView = (TextView) content.findViewById(R.id.subTitle);
    20. btnBack = content.findViewById(R.id.back);
    21. btnBack.setOnClickListener(new View.OnClickListener() {
    22. @Override
    23. public void onClick(View v) {
    24. invokePageBackEvent();
    25. }
    26. });
    27. optionContainer = content.findViewById(R.id.options);
    28. btHome = content.findViewById(R.id.home);
    29. int statusBarHeight = H5StatusBarUtils.getStatusBarHeight(context);
    30. content.setPadding(0, statusBarHeight, 0, 0);
    31. btHome.setOnClickListener(new View.OnClickListener() {
    32. @Override
    33. public void onClick(View v) {
    34. invokeHomeClickEvent();
    35. }
    36. });
    37. options1 = content.findViewById(R.id.options1);
    38. options1.setOnClickListener(new View.OnClickListener() {
    39. @Override
    40. public void onClick(View v) {
    41. invokeOptionClickEvent(1, false);
    42. }
    43. });
    44. }
    45. @Override
    46. public int getBackgroundColor() {
    47. return content.getContentBgView().getColor();
    48. }
    49. @Override
    50. public void setBackgroundAlphaValue(int i) {
    51. content.getContentBgView().setAlpha(i);
    52. }
    53. @Override
    54. public void setBackgroundColor(int i) {
    55. if ((i & 0xffffff) == 0xffffff) {
    56. mainTitleView.setTextColor(Color.BLACK);
    57. } else {
    58. mainTitleView.setTextColor(Color.WHITE);
    59. }
    60. content.getContentBgView().setColor(i);
    61. notifyTitleBarChanged();
    62. }
    63. @Override
    64. public String getTitle() {
    65. return mainTitleView.getText().toString();
    66. }
    67. @Override
    68. public void setTitle(String s) {
    69. mainTitleView.setText(s);
    70. }
    71. @Override
    72. public void setSubTitle(String s) {
    73. subTitleView.setText(s);
    74. }
    75. @Override
    76. public void setTitleImage(Bitmap bitmap) {
    77. }
    78. @Override
    79. public TextView getMainTitleView() {
    80. return mainTitleView;
    81. }
    82. @Override
    83. public TextView getSubTitleView() {
    84. return subTitleView;
    85. }
    86. @Override
    87. public void resetTitle() {
    88. content.getContentBgView().setColor(context.getResources().getColor(R.color.colorPrimary));
    89. }
    90. @Override
    91. public void showCloseButton(boolean b) {
    92. }
    93. @Override
    94. public View getContentView() {
    95. return content;
    96. }
    97. @Override
    98. public void showBackButton(boolean b) {
    99. btnBack.setVisibility(b ? View.VISIBLE : View.GONE);
    100. }
    101. @Override
    102. public void showBackHome(boolean b) {
    103. btHome.setVisibility(b ? View.VISIBLE : View.GONE);
    104. }
    105. @Override
    106. public void showOptionMenu(boolean b) {
    107. optionContainer.setVisibility(b ? View.VISIBLE : View.GONE);
    108. options1.setVisibility(b ? View.VISIBLE : View.GONE);
    109. }
    110. @Override
    111. public View getOptionMenuContainer(int i) {
    112. if (i == 1) {
    113. return options1;
    114. }
    115. return optionContainer;
    116. }
    117. @Override
    118. public void setOptionMenu(boolean reset, boolean override, boolean isTinyApp, List<MenuData> menus) {
    119. for (int i = 0; i < 2 && i < menus.size(); i++) {
    120. MenuData menuData = menus.get(i);
    121. if (isTinyApp) {
    122. String iconUrl = menuData.getIcon();
    123. if (!TextUtils.isEmpty(iconUrl)) {
    124. H5ImageUtil.loadImage(iconUrl, new H5ImageListener() {
    125. @Override
    126. public void onImage(Bitmap bitmap) {
    127. ((ImageView)options1.findViewById(R.id.o1image)).setImageBitmap(bitmap);
    128. }
    129. });
    130. }
    131. }
    132. }
    133. }
    134. @Override
    135. public void showTitleLoading(boolean b) {
    136. }
    137. @Override
    138. public View getPopAnchor() {
    139. return optionContainer;
    140. }
    141. }

设置小程序的 OptionMenu

  1. 右键单击 res 文件夹下的 layout 文件夹,选择 New > XML > Layout XML File,按 Enter 键。
    1
  2. 输入 Layout File Name,单击 Finish
    6
  3. layout_tiny_right.xml 文件中添加如下代码,设置 OptionMenu 控制区的布局。
    1. <?xml version="1.0" encoding="utf-8"?>
    2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3. android:layout_width="wrap_content"
    4. android:layout_height="match_parent"
    5. android:layout_gravity="center_vertical">
    6. <LinearLayout
    7. android:id="@+id/option_bg"
    8. android:background="#9fffffff"
    9. android:layout_width="wrap_content"
    10. android:layout_height="42dp"
    11. android:layout_gravity="center_vertical"
    12. android:gravity="center_vertical">
    13. <ImageView
    14. android:id="@+id/more"
    15. android:layout_width="26dp"
    16. android:layout_height="26dp"
    17. android:src="@drawable/icon_more"/>
    18. <ImageView
    19. android:id="@+id/close"
    20. android:layout_width="26dp"
    21. android:layout_height="26dp"
    22. android:layout_marginLeft="12dp"
    23. android:src="@drawable/icon_miniprogram_close"/>
    24. </LinearLayout>
    25. </FrameLayout>
  4. 创建 TinyOptionMenuView 类。
    7
  5. 在 TinyOptionMenuView 类中添加如下代码实现自定义 OptionMenu 控制区。

    1. public class TinyOptionMenuView extends AbsTinyOptionMenuView {
    2. private View container;
    3. private ImageView ivMore;
    4. private View ivClose;
    5. private Context context;
    6. private View bgView;
    7. public TinyOptionMenuView(Context context) {
    8. this.context = context;
    9. ViewGroup parent = null;
    10. if (context instanceof Activity) {
    11. parent = (ViewGroup) ((Activity) context).findViewById(android.R.id.content);
    12. }
    13. container = LayoutInflater.from(context).inflate(R.layout.layout_tiny_right, parent, false);
    14. ivClose = container.findViewById(R.id.close);
    15. ivMore = (ImageView) container.findViewById(R.id.more);
    16. bgView = container.findViewById(R.id.option_bg);
    17. }
    18. @Override
    19. public View getView() {
    20. return container;
    21. }
    22. @Override
    23. public void setOptionMenuOnClickListener(View.OnClickListener onClickListener) {
    24. ivMore.setOnClickListener(onClickListener);
    25. }
    26. @Override
    27. public void setCloseButtonOnClickListener(View.OnClickListener onClickListener) {
    28. ivClose.setOnClickListener(onClickListener);
    29. }
    30. @Override
    31. public void setCloseButtonOnLongClickListener(View.OnLongClickListener onLongClickListener) {
    32. ivClose.setOnLongClickListener(onLongClickListener);
    33. }
    34. @Override
    35. public void onStateChanged(TinyAppActionState state) {
    36. if (state == null) {
    37. ivMore.setImageDrawable(context.getResources().getDrawable(R.drawable.icon_more));
    38. } else if (state.getAction().equals(TinyAppActionState.ACTION_LOCATION)) {
    39. ivMore.setImageDrawable(context.getResources().getDrawable(R.drawable.icon_miniprogram_location));
    40. }
    41. }
    42. @Override
    43. protected void onTitleChange(final H5TitleView title) {
    44. super.onTitleChange(title);
    45. int color = title.getBackgroundColor();
    46. if ((color & 0xffffff) == 0xffffff) {
    47. bgView.setBackgroundColor(Color.RED);
    48. } else {
    49. bgView.setBackgroundColor(Color.GREEN);
    50. }
    51. }
    52. @Override
    53. public void setH5Page(H5Page h5Page) {
    54. super.setH5Page(h5Page);
    55. // title becomes available from here.
    56. if (getTitleBar().getBackgroundColor() == -1) {
    57. bgView.setBackgroundColor(Color.RED);
    58. }
    59. }
    60. @Override
    61. public void hideOptionMenu() {
    62. }
    63. }
  6. 在 MyApplication 类中的 IInitCallback 初始化回调中添加如下代码实现自定义标题栏和自定义右上角配置栏。

    1. // 自定义标题栏
    2. MPNebula.setCustomViewProvider(new H5ViewProvider() {
    3. @Override
    4. public H5TitleView createTitleView(Context context) {
    5. // 返回自定义 title
    6. return new TinyNavigationBar(context);
    7. }
    8. @Override
    9. public H5NavMenuView createNavMenu() {
    10. return null;
    11. }
    12. @Override
    13. public H5PullHeaderView createPullHeaderView(Context context, ViewGroup viewGroup) {
    14. return null;
    15. }
    16. @Override
    17. public H5WebContentView createWebContentView(Context context) {
    18. return null;
    19. }
    20. });
    21. // 自定义小程序右上角配置栏
    22. H5Utils.setProvider(TinyOptionMenuViewProvider.class.getName(), new TinyOptionMenuViewProvider() {
    23. @Override
    24. public AbsTinyOptionMenuView createView(Context context) {
    25. return new TinyOptionMenuView(context);
    26. }
    27. });

    8

运行小程序查看设置后的导航栏和 OptionMenu

  1. 单击 Run 运行程序到真机上。
  2. 单击 Hello World! 启动小程序。打开应用后在小程序加载时界面如下,可以看到自定义的右上角配置栏。
  3. 单击 基础组件 下的 图标 可以看到 Icon 页中的自定义导航栏布局。