【源码剖析】Launcher 8.0 源码 (9) --- Launcher 启动流程 第四步之第2小步OverViewPanel及其三个按钮

Launcher8.0启动流程的第四步,第2小步。定义OverViewPanel,关于OverViewPanel的布局整体在res里面以xml文件形式存在,而对于其细节层面,比如点击之后有什么用则再java层详细定义,而第2小步则是定义OverViewPanel三个按钮的功能。

 

在setupView的完整源码,以setupOverviewPanel方法为分界线,分为3小步。说明setupOverviewPanel非常复杂。和setupview方法一样,setupOverviewPanel也是在Launcher类里面。所创建内容服务于Launcher整体。

那么什么是OverviewPanel?

在Launcher使用时,长按桌面空白处,我们会发现,workspace缩小,hotseat消失,并且在下方出现三个选项:wallpapers,widget,home settings  这个提供特殊选项的栏,就叫做OverviewPanel

 

 

其源码如下:

private void setupOverviewPanel() {
    mOverviewPanel = (ViewGroup) findViewById(R.id.overview_panel);

    View wallpaperButton = findViewById(R.id.wallpaper_button);
    new OverviewButtonClickListener(ControlType.WALLPAPER_BUTTON) {
        @Override
        public void handleViewClick(View view) {
            onClickWallpaperPicker(view);
        }
    }.attachTo(wallpaperButton);
    wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());

    mWidgetsButton = findViewById(R.id.widget_button);
    new OverviewButtonClickListener(ControlType.WIDGETS_BUTTON) {
        @Override
        public void handleViewClick(View view) {
            onClickAddWidgetButton(view);
        }
    }.attachTo(mWidgetsButton);
    mWidgetsButton.setOnTouchListener(getHapticFeedbackTouchListener());

    View settingsButton = findViewById(R.id.settings_button);
    boolean hasSettings = hasSettings();
    if (hasSettings) {
        new OverviewButtonClickListener(ControlType.SETTINGS_BUTTON) {
            @Override
            public void handleViewClick(View view) {
                onClickSettingsButton(view);
            }
        }.attachTo(settingsButton);
        settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());
    } else {
        settingsButton.setVisibility(View.GONE);
    }

    mOverviewPanel.setAlpha(0f);
}

 

源码逻辑清晰,首先获取overview_panel的View,然后依次创建wallpaper,widget,settings这3个buttom。

 

overview_panel是oncreate流程第三步统一创建对象的时候,在UI布局文件Launcher.xml里面提到的多个组成Launcher的其中之一。核心就是三个button。

 

首先认真研读第一个wallpaperButton 的创建,而后举一反三。

 

 View wallpaperButton = findViewById(R.id.wallpaper_button);
 new OverviewButtonClickListener(ControlType.WALLPAPER_BUTTON) {
        @Override
        public void handleViewClick(View view) {
            onClickWallpaperPicker(view);
        }
    }.attachTo(wallpaperButton);
    wallpaperButton.setOnTouchListener(getHapticFeedbackTouchListener());

这里简化代码一共有三步:

创建View对象wallpaperButton

创建listener并绑定到View上。

new OverviewButtonClickListener().attachTo(wallpaperButton);

View.setOnTouchListener

首先关注view的获取。

Launcher.xml里面有一栏说明Launcher的overview_panel布局是调用了overview_panel.xml

<include layout="@layout/overview_panel"
    android:id="@+id/overview_panel"
    android:visibility="gone" />

 

然后看overview_panel.xml 充分简化都的代码,一个线性布局,里面有三个textView,对应三个button

<LinearLayout >
    <TextView   android:id="@+id/wallpaper_button"/>
    <TextView   android:id="@+id/widget_button"/>
    <TextView   android:id="@+id/settings_button" />
</LinearLayout>

 

接着创建clicklistener并attach。

 

public void attachTo(View v) {
    v.setOnClickListener(this);
    v.setOnLongClickListener(this);
}

 

其意思是将传入的View给定方法的listener。

所以new OverviewButtonClickListener().attachTo(wallpaperButton);

的含义是将创建的类的onclick方法绑定到wallpaperButton。

 

下面是OverviewButtonClickListener类的onclick和onLongClick方法的源码。

@Override
public void onClick(View view) {
    if (shouldPerformClick(view)) {
        handleViewClick(view, Action.Touch.TAP);
    }
}
@Override
public boolean onLongClick(View view) {
    if (shouldPerformClick(view)) {
        handleViewClick(view, Action.Touch.LONGPRESS);
    }
    return true;
}

 

在OverviewButtonClickListener这个自定义的buttonlistener里面,点击和长按都是触发handleViewClick方法。

 

而我们创建的OverviewButtonClickListener则是重写了handleViewClick方法。

   public void handleViewClick(View view) {
            onClickWallpaperPicker(view);
        }

于是,这里创建对象并attach,就是当我们点击这个按钮时,要触发重写的方法。在wallpaperButton里面,我们写的是onClickWallpaperPicker(view)。

 

看到这里,我们再回去看三个button的定义,都是在三段式,主要在OverviewButtonClickListener的重写方法上有区别。

 

然后就是wallpaperButton.setOnTouchListener();就是绑定点击响应。

 

接下来,认真看三个click方法的代码码

 

首先是onClickWallpaperPicker进行大幅度删减的代码

public void onClickWallpaperPicker(View v) {
    Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER)
            .putExtra(Utilities.EXTRA_WALLPAPER_OFFSET, offset);
    startActivityForResult(intent);
}

 

从给出的代码可以看出,这个按钮的功能是通过”Intent.ACTION_SET_WALLPAPER”来启动对应的应用。

 

手机中,提供设置壁纸功能的应用,比如图库,会打开此intent。 而Launcher在onclick被点击时就会启动对应的应用。

 

完整代码中有一部分关于intent的详细设定,以及一些保护措施。 但都是为了打开一个可以设壁纸的应用所服务。

 

 

接着是onClickAddWidgetButton方法,也是精简版。

public void onClickAddWidgetButton(View view) {
        showWidgetsView(true /* animated */, true /* resetPageToZero */);

}

 

void showWidgetsView(boolean animated, boolean resetPageToZero) {
    showAppsOrWidgets(State.WIDGETS, animated, false);
}

 

private boolean showAppsOrWidgets(State toState, boolean animated, boolean focusSearchBar) {
    if (toState == State.APPS) {
        mStateTransitionAnimation.startAnimationToAllApps(animated, focusSearchBar);
    } else {
        mStateTransitionAnimation.startAnimationToWidgets(animated);
    }
    return true;
}

 

从代码可以看到,是一个递进调用,过程中对state进行设置,最终调用了mStateTransitionAnimation这个对象的方法。

 

mStateTransitionAnimation是在Launcher流程第三步创建的第三个对象,负责不同模式间的切换,在onClickAddWidgetButton中完成的是从overview模式到widget模式的切换。

 

最后是onClickSettingsButton方法

public void onClickSettingsButton(View v) {
    Intent intent = new Intent(Intent.ACTION_APPLICATION_PREFERENCES)
            .setPackage(getPackageName());
    intent.setSourceBounds(getViewBounds(v));
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent, getActivityLaunchOptions(v));
}

 

从代码看出,使用Intent.ACTION_APPLICATION_PREFERENCES来启动Launcher的Settings activity。

 

这样overviewpanel的三个选项就都完成了。其中wallpapers和settings是启动新的activity , widget是Launcher之间的模式变化。

 

以上就是第二小步。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

第四步的setupView的第三小步:对workspace进行基本绑定。

 

mWorkspace.setOnLongClickListener(this);
mWorkspace.setup(mDragController);
mWorkspace.lockWallpaperToDefaultPage();
mWorkspace.bindAndInitFirstWorkspaceScreen( );

mDragController.addDragListener(mWorkspace);

 

首先在workspace上绑定onlongclick方法。里面绑定的是Launcher里面的onlongclick。于是当长按workspace的时候,就会启用Launcher的onlongclick方法。

 

下面是Launcher中onlongclick关于workspace部分。

@Override
public boolean onLongClick(View v) {
    if (v instanceof Workspace) {
        if (!mWorkspace.isInOverviewMode()) {
                getUserEventDispatcher().logActionOnContainer(Action.Touch.LONGPRESS,
                        Action.Direction.NONE, ContainerType.WORKSPACE,
                        mWorkspace.getCurrentPage());
                showOverviewMode(true);
}

}
}

 

Launcher的onlongclick不仅仅绑定在workspace。还有其他模块也绑定。所以触发时需要进行判断。这里在workspace长按,如果长按的时候,不少overview这个模式,则进入overview这个模式。

 

mWorkspace.setup(mDragController); 在workspace中传入dragcontroller。 Dragcontroller的用途广泛,和拖拽有关的,比如,拖拽时顶部出现的选项栏等等都由Dragcontroller控制。

 

 

mWorkspace.lockWallpaperToDefaultPage(); 是设workspace时背景壁纸的偏移量的,Launcher有个壁纸随页面滑动的功能,也就是长壁纸功能。在此功能下,开机时的那一张被设为默认的壁纸起始页面。

 

mWorkspace.bindAndInitFirstWorkspaceScreen(null ); 绑定起始桌面的默认google search的。正如之前提到,google在开发Launcher的时候特地留了一个google search widget的入口。

 

mDragController.addDragListener(mWorkspace); 给workspace监听drag的权限

 

第四步的setupView的第四小步:对allapp和DropTargetBar 及其他设定。


mDropTargetBar = (DropTargetBar) mDragLayer.findViewById(R.id.drop_target_bar);
mAppsView = (AllAppsContainerView) findViewById(R.id.apps_view);
if (mLauncherCallbacks != null && mLauncherCallbacks.getAllAppsSearchBarController() != null) {
    mAppsView.setSearchBarController(mLauncherCallbacks.getAllAppsSearchBarController());
} else {
    mAppsView.setSearchBarController(new DefaultAppSearchController());
}
mDragController.setMoveTarget(mWorkspace);
mDragController.addDropTarget(mWorkspace);
mDropTargetBar.setup(mDragController);

 

设置allapp的搜索栏以及提供在workspace顶部能够显示选项按钮。

 

mDropTargetBar顶部选项按钮,是Launcher.xml的组件之一。

当拖动应用的时候,顶部会给出该应用能够供给的一些选项。

通常有info、remove、disable、uninstall

info:从allapp拖动应用到桌面会出现,将应用拖到info并松开会显示应用的参数

Remove:删掉桌面的快捷方式,allapp中仍然保留

Disable:禁用应用,针对系统应用,这些应用不能被删除,如有需要,可以选择禁用该应用的功能。比如平板的通话和短信功能。

Uninstall:对于用户安装的应用,在拖拽时顶部会有uninstall选项。这是用户在桌面删除手机中应用的唯一方法。  删除应用可以在设置或者其他应用管理软件里面进行。

 

 

猜你喜欢

转载自blog.csdn.net/dax120/article/details/81190716