Launcher3源码分析 — bindScreen的具体实现

来源:互联网 发布:哈希排序算法 编辑:程序博客网 时间:2024/04/27 21:22

前面讲到,在bindWorkspace中涉及了以下几个回调方法:

startBinding();bindScreens();bindWorkspaceItems();finishBindingItems();

Launcher类实现了这些回调接口,startBinding()主要完成了数据清空和状态重置等预备操作,这里不详细分析,接下来我们来看其他方法在Launcher类中的具体实现。


我们从bindScreen()开始,bindScreen完成了页面的添加工作,下面是页面添加的流程图:


由图可以看出,有3种类型的screen,有序Screen列表中包含的非空页面,空页面和自定义页面。在Launcher类中,bindScreens()的具体实现如下:

@Overridepublic void bindScreens(ArrayList<Long> orderedScreenIds) {    // 根据orderedScreenIds来添加页面    bindAddScreens(orderedScreenIds);    // 如果orderedScreenIds的大小为0,即没有添加任何页面,需要添加一个空的页面    if (orderedScreenIds.size() == 0) {        mWorkspace.addExtraEmptyScreen();    }    // 如果有自定义页面,则将自定义页面添加到最左    if (!mWorkspace.hasCustomContent() && hasCustomContentToLeft()) {        mWorkspace.createCustomContentPage();    }}


bindAddScreens(orderedScreenIds)的代码如下:
@Overridepublic void bindAddScreens(ArrayList<Long> orderedScreenIds) {    int count = orderedScreenIds.size();    for (int i = 0; i < count; i++) {        mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(orderedScreenIds.get(i));    }}


从insertNewWorkspaceScreenBeforeEmptyScreen()的名字可以看出,该方法的作用是把页面插到空页面之前,代码如下:

    public long insertNewWorkspaceScreenBeforeEmptyScreen(long screenId) {        // 查找页面插入的索引位置,如果有空页面,则在空页面之前插入        int insertIndex = mScreenOrder.indexOf(EXTRA_EMPTY_SCREEN_ID);        if (insertIndex < 0) {            insertIndex = mScreenOrder.size();        }        // 根据页面id和插入位置进行页面的插入        return insertNewWorkspaceScreen(screenId, insertIndex);    }

在Workspace中维护了两个与页面相关的集合:

    // 存储页面id为key,页面视图为value的HashMap    private HashMap<Long, CellLayout> mWorkspaceScreens = new HashMap<Long, CellLayout>();    // 有序的页面id列表    private ArrayList<Long> mScreenOrder = new ArrayList<Long>();


insertNewWorkspaceScreen完成了页面创建和插入操作,具体代码如下:

    public long insertNewWorkspaceScreen(long screenId, int insertIndex) {        if (mWorkspaceScreens.containsKey(screenId)) {            throw new RuntimeException("Screen id " + screenId + " already exists!");        }        // 创建页面视图        CellLayout newScreen = (CellLayout)                mLauncher.getLayoutInflater().inflate(R.layout.workspace_screen, null);        // 设置点击事件        newScreen.setOnLongClickListener(mLongClickListener);        newScreen.setOnClickListener(mLauncher);        newScreen.setSoundEffectsEnabled(false);                // 添加到相应的页面集合        mWorkspaceScreens.put(screenId, newScreen);        mScreenOrder.add(insertIndex, screenId);        // 将页面添加到Workspace中        addView(newScreen, insertIndex);        return screenId;    }


添加空页面的代码如下:
    public boolean addExtraEmptyScreen() {        // 空页面的id为EXTRA_EMPTY_SCREEN_ID        if (!mWorkspaceScreens.containsKey(EXTRA_EMPTY_SCREEN_ID)) {            // 没有指定插入的位置,则添加到最后的位置            insertNewWorkspaceScreen(EXTRA_EMPTY_SCREEN_ID);            return true;        }        return false;    }


添加自定义页面的代码如下:
     public void createCustomContentPage() {        CellLayout customScreen = (CellLayout)                mLauncher.getLayoutInflater().inflate(R.layout.workspace_screen, null);        mWorkspaceScreens.put(CUSTOM_CONTENT_SCREEN_ID, customScreen);        mScreenOrder.add(0, CUSTOM_CONTENT_SCREEN_ID);        // We want no padding on the custom content        customScreen.setPadding(0, 0, 0, 0);        addFullScreenPage(customScreen);        // Ensure that the current page and default page are maintained.        mDefaultPage = mOriginalDefaultPage + 1;        // Update the custom content hint        mLauncher.updateCustomContentHintVisibility();        if (mRestorePage != INVALID_RESTORE_PAGE) {            mRestorePage = mRestorePage + 1;        } else {            setCurrentPage(getCurrentPage() + 1);        }    }


空页面和自定义页面的id定义:
    private final static long EXTRA_EMPTY_SCREEN_ID = -201;    private final static long CUSTOM_CONTENT_SCREEN_ID = -301;


1 0
原创粉丝点击