Skip to content

通过 API 自定义 UI 元素

本节介绍如何通过 UI Extensions 提供的 API,对内置 UI 进行“运行时”的显示/隐藏与增删改,例如:

  • 顶部/底部工具栏(Top/Bottom Toolbar)
  • 面板(Panel,例如 Outline)
  • 视图设置栏(View Setting Bar)
  • 更多菜单(More Menu)

说明

以下示例以 SDK 自带的 samples/complete_pdf_viewer 为参考场景。示例代码通常添加在 PDFReaderFragment.java 中(在 mUiExtensionsManager = new UIExtensionsManager(...) 之后)。

1. 自定义顶部/底部工具栏(Top/Bottom Toolbar)

本节示例较多。建议先阅读“位置与索引说明”,再按“需求分类”快速定位对应用法。

1.1 位置与索引说明(重要)

在调用 addItem / removeItem / getItemByIndex 等 API 时,需要通过 工具栏名称(BarName)位置(TB_Position) 来定位“往哪一段工具栏、哪个区域”添加/移除 item。下面为相关枚举示意:

java
enum BarName {
    TOP_BAR,
    BOTTOM_BAR
}

enum TB_Position {
    Position_LT,
    Position_CENTER,
    Position_RB
}

使用说明

  • Phone/Tablet 差异:平板设备默认没有底部工具栏。
  • 位置选择
    • 添加到顶部工具栏时,请使用 Position_LTPosition_RB
    • 添加到底部工具栏时,请使用 Position_CENTER
    • 若位置选择不当,可能导致 item 发生重叠或布局异常。
  • 索引规则:手机端工具栏按"顶部左 / 顶部右 / 底部"分成 3 个区域,每个区域的按钮(item) 索引独立;平板端仅存在顶部左右两段。
  • 文本长度建议:为避免布局错乱,建议顶部工具栏文字不超过 15 个字符、底部工具栏不超过 8 个字符。

1.2 示例(按需求分类)

提示

平板与手机的内置 UI 布局存在差异;部分示例仅适用于手机或平板。请以示例标题/注释中的适用范围为准。

1.2.1 显示/隐藏工具栏

示例 1:隐藏顶部工具栏

java
mUiExtensionsManager.enableTopToolbar(false);

示例 2:隐藏底部工具栏(仅 Phone)

java
mUiExtensionsManager.enableBottomToolbar(false);

1.2.2 添加工具栏按钮

示例 3:向顶部工具栏左侧添加自定义按钮

工具栏按钮的创建与点击事件写法基本一致,差异主要在于 加入的位置(Position_LT / Position_RB索引(index)。以下是添加 “左侧按钮”示例:

java
BaseItemImpl mTopItem1 = new BaseItemImpl(getContext(), R.drawable.rd_delete_menu);

mTopItem1.setImageTintList(ColorStateList.valueOf(Color.WHITE));
mTopItem1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        UIToast.getInstance(getActivity()).show("Add an item in the left top toolbar at the second position.");
    }
});
mUiExtensionsManager.getBarManager().addItem(IBarsHandler.BarName.TOP_BAR, BaseBar.TB_Position.Position_LT, mTopItem1, 1);

示例 4:向顶部工具栏右侧添加自定义按钮

java
BaseItemImpl mTopItem2 = new BaseItemImpl(getContext(), R.drawable.rd_delete_menu);

mTopItem2.setImageTintList(ColorStateList.valueOf(Color.WHITE));
mTopItem2.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        UIToast.getInstance(getActivity()).show("Add an item in the right top toolbar at the first position");
    }
});
mUiExtensionsManager.getBarManager().addItem(IBarsHandler.BarName.TOP_BAR, BaseBar.TB_Position.Position_RB, mTopItem2, 0);

示例 5:向底部工具栏添加按钮(仅 Phone)

java
mUiExtensionsManager.getBarManager().addItem(
        IBarsHandler.BarName.BOTTOM_BAR,
        BaseBar.TB_Position.Position_CENTER,
        "",
        R.drawable.ic_bar_item_more,
        0,
        new IBarsHandler.IItemClickListener() {
            @Override
            public void onClick(View v) {
                UIToast.getInstance(getActivity()).show("Add an item to the bottom toolbar at the first position.");
            }
        }
);

示例 6:向底部工具栏添加自定义样式按钮(仅 Phone)

java
BaseItemImpl mSettingBtn = new BaseItemImpl(this.getContext(), R.drawable.rd_annot_create_ok_selector);
mSettingBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        UIToast.getInstance(getActivity()).show("Add an item with custom style to the bottom toolbar at the second position.");
    }
});
mUiExtensionsManager.getBarManager().addItem(IBarsHandler.BarName.BOTTOM_BAR, BaseBar.TB_Position.Position_CENTER, mSettingBtn, 1);

1.2.3 移除工具栏按钮

示例 7:按 index 移除按钮(仅 Phone)

java
mUiExtensionsManager.getBarManager().removeItem(
        IBarsHandler.BarName.BOTTOM_BAR,
        BaseBar.TB_Position.Position_CENTER,
        0
);

示例 8:按 BaseItem 对象移除按钮

java
mUiExtensionsManager.getBarManager().removeItem(
        IBarsHandler.BarName.TOP_BAR,
        BaseBar.TB_Position.Position_LT,
        mTopItem1
);

示例 9:移除底部工具栏所有按钮(仅 Phone)

java
mUiExtensionsManager.getBarManager().removeAllItems(IBarsHandler.BarName.BOTTOM_BAR);

1.2.4 动态控制指定按钮显示/隐藏

示例 10:显示/隐藏指定按钮(以 More Menu 按钮为例)

java
// 获取需要显示/隐藏的按钮引用
final IBarsHandler barsHandler = (IBarsHandler) mUiExtensionsManager.getBarManager();
final IBaseItem moreItem = barsHandler.getItemByIndex(
        IBarsHandler.BarName.TOP_BAR,
        BaseBar.TB_Position.Position_RB,
        1
);

// 添加一个按钮,点击后隐藏 "moreItem"
BaseItemImpl topItem = new BaseItemImpl(getContext(), R.drawable.rd_delete_menu);
topItem.setImageTintList(ColorStateList.valueOf(Color.WHITE));
topItem.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // 隐藏 "moreItem"
        mUiExtensionsManager.getBarManager().removeItem(
                IBarsHandler.BarName.TOP_BAR,
                BaseBar.TB_Position.Position_RB,
                moreItem
        );
    }
});
mUiExtensionsManager.getBarManager().addItem(IBarsHandler.BarName.TOP_BAR, BaseBar.TB_Position.Position_LT, topItem, 1);

// 添加一个按钮,点击后显示 "moreItem"
BaseItemImpl topItem2 = new BaseItemImpl(getContext(), R.drawable.common_add_icon);
topItem2.setImageTintList(ColorStateList.valueOf(Color.WHITE));
topItem2.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // 显示 "moreItem"
        if (AppDisplay.isPad())
            mUiExtensionsManager.getBarManager().addItem(IBarsHandler.BarName.TOP_BAR, BaseBar.TB_Position.Position_RB, moreItem, 3);
        else
            mUiExtensionsManager.getBarManager().addItem(IBarsHandler.BarName.TOP_BAR, BaseBar.TB_Position.Position_RB, moreItem, 1);
    }
});
mUiExtensionsManager.getBarManager().addItem(IBarsHandler.BarName.TOP_BAR, BaseBar.TB_Position.Position_LT, topItem2, 2);

1.2.5 工具栏结构调整(工具栏 / 标签栏/ 入口)

示例 11:移除整个底部工具栏(仅 Phone)

java
mUiExtensionsManager.getBarManager().removeToolBar(IBarsHandler.BarName.BOTTOM_BAR);

示例 12:添加自定义工具栏

java
View topView = View.inflate(getContext(), R.layout.test_top_layout, null);
mUiExtensionsManager.getBarManager().addCustomToolBar(IBarsHandler.BarName.TOP_BAR, topView);

示例 13:移除顶部工具栏中间区域的 “表单” 标签

java
mUiExtensionsManager.getMainFrame().removeTab(ToolbarItemConfig.ITEM_FORM_TAB);

示例 14:移除 “视图” 入口

java
if (AppDisplay.isPad())
    mUiExtensionsManager.getMainFrame().removeTab(ToolbarItemConfig.ITEM_VIEW_TAB);
else
    mUiExtensionsManager.getBarManager().removeItem(
            IBarsHandler.BarName.BOTTOM_BAR,
            BaseBar.TB_Position.Position_CENTER,
            1
    );

2. 自定义面板(Panel)

2.1 API 概览

java
// 添加子面板。若面板类型已存在,则不会重复添加。
public void addPanel(PanelSpec panelSpec);
public void addPanel(int index, PanelSpec panelSpec);

// 移除子面板。
public void removePanel(int panelType);
public void removePanel(PanelSpec panelSpec);

使用 removePanel(PanelSpec) 移除内置面板时,可参考下面的内置面板与 PanelSpec 对照表;使用 removePanel(int panelType) 时,则需传入对应的 panelType(表格中的 panelType(integer) 列)。

面板PanelSpecpanelType(integer)
BookmarksPanelSpec.BOOKMARKS0
OutlinePanelSpec.OUTLINE1
CommentsPanelSpec.ANNOTATIONS2
AttachmentsPanelSpec.ATTACHMENTS3
Digital SignaturesPanelSpec.SIGNATURES4

2.2 示例(按需求分类)

2.2.1 移除内置面板

示例 1:通过按钮移除 Outline 面板
java
BaseItemImpl removePanel = new BaseItemImpl(getActivity(), R.drawable.rd_delete_menu);

removePanel.setImageTintList(ColorStateList.valueOf(Color.WHITE));

removePanel.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mUiExtensionsManager.getPanelManager().removePanel(PanelSpec.OUTLINE);
    }
});
mUiExtensionsManager.getBarManager().addItem(IBarsHandler.BarName.TOP_BAR, BaseBar.TB_Position.Position_LT, removePanel, 1);

2.2.2 添加自定义面板

示例 2:在点击事件中添加一个自定义面板
java
BaseItemImpl customPanel = new BaseItemImpl(getActivity(), R.drawable.common_add_icon);

customPanel.setImageTintList(ColorStateList.valueOf(Color.WHITE));

customPanel.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mUiExtensionsManager.getPanelManager().addPanel(new CustomPanel(getContext()));
    }
});
mUiExtensionsManager.getBarManager().addItem(IBarsHandler.BarName.TOP_BAR, BaseBar.TB_Position.Position_LT, customPanel, 1);

CustomPanel 需实现 PanelSpec 接口,例如:

java
package com.foxit.home;

import android.content.Context;
import android.content.res.ColorStateList;
import android.view.View;
import android.widget.TextView;

import com.foxit.uiextensions.controls.panel.PanelSpec;
import com.foxit.uiextensions.controls.toolbar.BaseBar;
import com.foxit.uiextensions.controls.toolbar.IBaseItem;
import com.foxit.uiextensions.controls.toolbar.impl.BaseItemImpl;
import com.foxit.uiextensions.controls.toolbar.impl.TopBarImpl;

public class CustomPanel implements PanelSpec {

    private Context mContext;

    public CustomPanel(Context context) {
        mContext = context;
    }

    @Override
    public int getIcon() {
        return R.drawable.toolbar_thumbnail_icon;
    }

    @Override
    public ColorStateList getIconTint() {
        return null;
    }

    @Override
    public int getPanelType() {
        return 100;
    }

    @Override
    public View getTopToolbar() {
        TopBarImpl topBar = new TopBarImpl(mContext);
        IBaseItem baseItem = new BaseItemImpl(mContext);
        baseItem.setText("Custom Panel");
        topBar.addView(baseItem, BaseBar.TB_Position.Position_CENTER);
        return topBar.getContentView();
    }

    @Override
    public View getContentView() {
        TextView textView = new TextView(mContext);
        textView.setText("This is empty");
        return textView;
    }

    @Override
    public void onActivated() {

    }

    @Override
    public void onDeactivated() {

    }
}

3. 自定义视图设置栏(View Setting Bar)

可通过 setVisible 控制视图设置栏(View Setting Bar)中指定选项的显示/隐藏。

3.1 API 概览

java
public void setVisible(int type, boolean visible);

3.2 type 取值(常量)

java
IViewSettingsWindow.TYPE_SINGLE_PAGE        // 1
IViewSettingsWindow.TYPE_FACING_PAGE        // 2
IViewSettingsWindow.TYPE_COVER_PAGE         // 4
IViewSettingsWindow.TYPE_DAY                // 8
IViewSettingsWindow.TYPE_PAGE_COLOR         // 16
IViewSettingsWindow.TYPE_NIGHT              // 32
IViewSettingsWindow.TYPE_CONTINUOUS_PAGE    // 64
IViewSettingsWindow.TYPE_FIT_PAGE           // 128
IViewSettingsWindow.TYPE_FIT_WIDTH          // 256
IViewSettingsWindow.TYPE_REFLOW             // 288
IViewSettingsWindow.TYPE_CROP               // 320
IViewSettingsWindow.TYPE_TTS                // 384
IViewSettingsWindow.TYPE_AUTO_FLIP          // 512
IViewSettingsWindow.TYPE_ROTATE_VIEW        // 544
IViewSettingsWindow.TYPE_PAN_ZOOM           // 576
IViewSettingsWindow.TYPE_RIGHT_TO_LEFT      // 608

3.3 示例

示例 1:隐藏 “Fit Width” 选项

java
mUiExtensionsManager.getSettingWindow().setVisible(IViewSettingsWindow.TYPE_FIT_WIDTH, false);

4. 自定义更多菜单(More Menu)

More Menu 支持隐藏指定菜单组/菜单项,也支持新增自定义菜单组与菜单项。

4.1 API 概览

java
// 通过 IMenuItem 添加菜单项。
IMenuGroup.addItem(IMenuItem item);
IMenuGroup.addItem(CharSequence title);
IMenuGroup.addItem(Drawable icon, CharSequence title);

// 切换可见性。
IMenuGroup.setVisible(boolean visible);
IMenuItem.setVisible(boolean visible);

4.2 示例

示例 1:隐藏某个菜单组

java
IMenuView menuView = mUiExtensionsManager.getMenuView();
IMenuGroup menuGroup = menuView.getGroup(MoreMenuConstants.GROUP_ACTION_MENU_PRIMARY);
menuGroup.setVisible(false);

示例 2:隐藏某个菜单项

java
IMenuView menuView = mUiExtensionsManager.getMenuView();
IMenuGroup menuGroup = menuView.getGroup(MoreMenuConstants.GROUP_ACTION_MENU_SECONDARY);
IMenuItem menuItem = menuGroup.getItem(MoreMenuConstants.ITEM_SECONDARY_PRINT);
menuItem.setVisible(false);

示例 3:新增自定义菜单组与菜单项

java
IMenuView menuView = mUiExtensionsManager.getMenuView();
IMenuGroup customGroup = menuView.addGroup("Custom Group");
IMenuItem item1 = customGroup.addItem(AppResource.getDrawable(getActivity(), R.drawable.rd_comment_menu), "comment");
item1.setOnMenuItemClickListener(new IMenuItem.OnMenuItemClickListener() {
    @Override
    public void onClick(IMenuItem item) {
        UIToast.getInstance(getActivity()).show("I am item1");
    }
});
IMenuItem item2 = customGroup.addItem(AppResource.getDrawable(getActivity(), R.drawable.rd_delete_menu), "delete");
item2.setOnMenuItemClickListener(new IMenuItem.OnMenuItemClickListener() {
    @Override
    public void onClick(IMenuItem item) {
        UIToast.getInstance(getActivity()).show("I am item2");
    }
});

4.3 内置菜单项参考(MoreMenuConstants)

在隐藏内置菜单组/菜单项时,建议优先使用 SDK 提供的 MoreMenuConstants 常量进行定位。以下表格以 complete_pdf_viewer 的默认 More Menu 为参考列出常用项;实际可见项可能因授权、模块启用情况、设备形态(Phone/Tablet)或产品版本而不同

4.3.1 菜单组(Group)

菜单组常量ID
主菜单组GROUP_ACTION_MENU_PRIMARY1000
次级菜单组GROUP_ACTION_MENU_SECONDARY1001

4.3.2 菜单项(Item)

菜单组菜单项常量ID
GROUP_ACTION_MENU_PRIMARYITEM_PRIMARY_PROTECT1
GROUP_ACTION_MENU_PRIMARYITEM_PRIMARY_COMMENT_FIELDS2
GROUP_ACTION_MENU_SECONDARYITEM_SECONDARY_SAVE_AS1
GROUP_ACTION_MENU_SECONDARYITEM_SECONDARY_REDUCE_FILE_SIZE2
GROUP_ACTION_MENU_SECONDARYITEM_SECONDARY_PRINT3
GROUP_ACTION_MENU_SECONDARYITEM_SECONDARY_FLATTEN4
GROUP_ACTION_MENU_SECONDARYITEM_SECONDARY_SCREEN5

4.3.3 子项(Sub-item)

部分菜单项包含子项(例如 ITEM_PRIMARY_PROTECTITEM_PRIMARY_COMMENT_FIELDS)。如需定位这些子项,可参考下表中的常量与 ID(取值以 MoreMenuConstants 定义为准)。

菜单项(Item)子项常量(Sub-item)ID
ITEM_PRIMARY_PROTECTITEM_PROTECT_REDACTION1
ITEM_PRIMARY_PROTECTITEM_PROTECT_REMOVE_PASSWORD2
ITEM_PRIMARY_PROTECTITEM_PROTECT_FILE_ENCRYPTION3
ITEM_PRIMARY_PROTECTITEM_PROTECT_TRUSTED_CERTIFICATES4
ITEM_PRIMARY_COMMENT_FIELDSITEM_COMMENTS_FIELDS_IMPORT_COMMENTS1
ITEM_PRIMARY_COMMENT_FIELDSITEM_COMMENTS_FIELDS_EXPORT_COMMENTS2
ITEM_PRIMARY_COMMENT_FIELDSITEM_COMMENTS_FIELDS_SUMMARIZE_COMMENTS3
ITEM_PRIMARY_COMMENT_FIELDSITEM_COMMENTS_FIELDS_RESET_FORM_FIELDS4
ITEM_PRIMARY_COMMENT_FIELDSITEM_COMMENTS_FIELDS_IMPORT_FORM_DATA5
ITEM_PRIMARY_COMMENT_FIELDSITEM_COMMENTS_FIELDS_EXPORT_FORM_DATA6